On Wed, Dec 12, 2012 at 4:34 PM, Brecht Van Lommel <[email protected]> wrote: > Hi, > > I'd be careful testing if this actually speeds things up, threading > overhead can be big especially on Xeon CPU's (maybe because they are > multi socket and not just multi core). For subsurf it only uses openmp > if the number of faces is > 1 million, otherwise it slowed down the > modifier stack a lot rendering Sintel scenes. > > Brecht. > > On Wed, Dec 12, 2012 at 6:04 AM, Campbell Barton <[email protected]> wrote: >> Revision: 52908 >> >> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52908 >> Author: campbellbarton >> Date: 2012-12-12 05:04:01 +0000 (Wed, 12 Dec 2012) >> Log Message: >> ----------- >> use openmp to thread some common bmesh operations >> - BM_mesh_elem_toolflags_ensure / bmo_flag_layer_alloc / bmo_flag_layer_free >> / bmo_flag_layer_clear >> - BM_mesh_select_flush >> - EDBM_index_arrays_init >> >> notes: >> - mostly use openmp `sections` to split operations on vert/edge/face since >> this is a fairly minor change. >> - split tool flag pool in 3, this means we can allocate exact sizes needed >> and iterate on them in threads without alloc'ing. >> >> Modified Paths: >> -------------- >> trunk/blender/source/blender/bmesh/bmesh_class.h >> trunk/blender/source/blender/bmesh/intern/bmesh_core.c >> trunk/blender/source/blender/bmesh/intern/bmesh_marking.c >> trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c >> trunk/blender/source/blender/bmesh/intern/bmesh_operators.c >> trunk/blender/source/blender/editors/mesh/editmesh_utils.c >> trunk/blender/source/blender/modifiers/intern/MOD_decimate.c >> >> Modified: trunk/blender/source/blender/bmesh/bmesh_class.h >> =================================================================== >> --- trunk/blender/source/blender/bmesh/bmesh_class.h 2012-12-12 04:50:53 >> UTC (rev 52907) >> +++ trunk/blender/source/blender/bmesh/bmesh_class.h 2012-12-12 05:04:01 >> UTC (rev 52908) >> @@ -187,8 +187,9 @@ >> /*element pools*/ >> struct BLI_mempool *vpool, *epool, *lpool, *fpool; >> >> - /*operator api stuff*/ >> - struct BLI_mempool *toolflagpool; >> + /*operator api stuff (must be all NULL or all alloc'd)*/ >> + struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; >> + >> int stackdepth; >> struct BMOperator *currentop; >> >> >> Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c >> =================================================================== >> --- trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2012-12-12 >> 04:50:53 UTC (rev 52907) >> +++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2012-12-12 >> 05:04:01 UTC (rev 52908) >> @@ -79,8 +79,8 @@ >> } >> >> /* allocate flags */ >> - if (bm->toolflagpool) { >> - v->oflags = BLI_mempool_calloc(bm->toolflagpool); >> + if (bm->vtoolflagpool) { >> + v->oflags = BLI_mempool_calloc(bm->vtoolflagpool); >> } >> >> if (!(create_flag & BM_CREATE_SKIP_CD)) { >> @@ -133,8 +133,8 @@ >> e->head.htype = BM_EDGE; >> >> /* allocate flags */ >> - if (bm->toolflagpool) { >> - e->oflags = BLI_mempool_calloc(bm->toolflagpool); >> + if (bm->etoolflagpool) { >> + e->oflags = BLI_mempool_calloc(bm->etoolflagpool); >> } >> >> e->v1 = v1; >> @@ -291,8 +291,8 @@ >> f->head.htype = BM_FACE; >> >> /* allocate flags */ >> - if (bm->toolflagpool) { >> - f->oflags = BLI_mempool_calloc(bm->toolflagpool); >> + if (bm->ftoolflagpool) { >> + f->oflags = BLI_mempool_calloc(bm->ftoolflagpool); >> } >> >> if (!(create_flag & BM_CREATE_SKIP_CD)) { >> @@ -512,8 +512,8 @@ >> if (v->head.data) >> CustomData_bmesh_free_block(&bm->vdata, &v->head.data); >> >> - if (bm->toolflagpool) { >> - BLI_mempool_free(bm->toolflagpool, v->oflags); >> + if (bm->vtoolflagpool) { >> + BLI_mempool_free(bm->vtoolflagpool, v->oflags); >> } >> BLI_mempool_free(bm->vpool, v); >> } >> @@ -532,8 +532,8 @@ >> if (e->head.data) >> CustomData_bmesh_free_block(&bm->edata, &e->head.data); >> >> - if (bm->toolflagpool) { >> - BLI_mempool_free(bm->toolflagpool, e->oflags); >> + if (bm->etoolflagpool) { >> + BLI_mempool_free(bm->etoolflagpool, e->oflags); >> } >> BLI_mempool_free(bm->epool, e); >> } >> @@ -555,8 +555,8 @@ >> if (f->head.data) >> CustomData_bmesh_free_block(&bm->pdata, &f->head.data); >> >> - if (bm->toolflagpool) { >> - BLI_mempool_free(bm->toolflagpool, f->oflags); >> + if (bm->ftoolflagpool) { >> + BLI_mempool_free(bm->ftoolflagpool, f->oflags); >> } >> BLI_mempool_free(bm->fpool, f); >> } >> @@ -1785,8 +1785,8 @@ >> bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2); >> >> /* deallocate edge and its two loops as well as f2 */ >> - if (bm->toolflagpool) { >> - BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags); >> + if (bm->etoolflagpool) { >> + BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags); >> } >> BLI_mempool_free(bm->epool, f1loop->e); >> bm->totedge--; >> @@ -1794,8 +1794,8 @@ >> bm->totloop--; >> BLI_mempool_free(bm->lpool, f2loop); >> bm->totloop--; >> - if (bm->toolflagpool) { >> - BLI_mempool_free(bm->toolflagpool, f2->oflags); >> + if (bm->ftoolflagpool) { >> + BLI_mempool_free(bm->ftoolflagpool, f2->oflags); >> } >> BLI_mempool_free(bm->fpool, f2); >> bm->totface--; >> >> Modified: trunk/blender/source/blender/bmesh/intern/bmesh_marking.c >> =================================================================== >> --- trunk/blender/source/blender/bmesh/intern/bmesh_marking.c 2012-12-12 >> 04:50:53 UTC (rev 52907) >> +++ trunk/blender/source/blender/bmesh/intern/bmesh_marking.c 2012-12-12 >> 05:04:01 UTC (rev 52908) >> @@ -44,8 +44,6 @@ >> >> static void recount_totsels(BMesh *bm) >> { >> - BMIter iter; >> - BMElem *ele; >> const char iter_types[3] = {BM_VERTS_OF_MESH, >> BM_EDGES_OF_MESH, >> BM_FACES_OF_MESH}; >> @@ -58,11 +56,16 @@ >> tots[1] = &bm->totedgesel; >> tots[2] = &bm->totfacesel; >> >> +#pragma omp parallel for schedule(dynamic) >> for (i = 0; i < 3; i++) { >> - ele = BM_iter_new(&iter, bm, iter_types[i], NULL); >> - for ( ; ele; ele = BM_iter_step(&iter)) { >> - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] >> += 1; >> + BMIter iter; >> + BMElem *ele; >> + int count = 0; >> + >> + BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { >> + if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += >> 1; >> } >> + *tots[i] = count; >> } >> } >> >> @@ -161,34 +164,45 @@ >> >> int ok; >> >> - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { >> - if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && >> - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && >> - !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) >> + /* we can use 2 sections here because the second loop isnt checking >> edge selection */ >> +#pragma omp parallel sections >> + { >> +#pragma omp section >> { >> - BM_elem_flag_disable(e, BM_ELEM_SELECT); >> + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { >> + if (!(BM_elem_flag_test(e->v1, >> BM_ELEM_SELECT) && >> + BM_elem_flag_test(e->v2, >> BM_ELEM_SELECT) && >> + !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) >> + { >> + BM_elem_flag_disable(e, >> BM_ELEM_SELECT); >> + } >> + } >> } >> - } >> >> - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { >> - ok = TRUE; >> - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { >> - l_iter = l_first = BM_FACE_FIRST_LOOP(f); >> - do { >> - if (!BM_elem_flag_test(l_iter->v, >> BM_ELEM_SELECT)) { >> +#pragma omp section >> + { >> + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { >> + ok = TRUE; >> + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { >> + l_iter = l_first = >> BM_FACE_FIRST_LOOP(f); >> + do { >> + if >> (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { >> + ok = FALSE; >> + break; >> + } >> + } while ((l_iter = l_iter->next) != >> l_first); >> + } >> + else { >> ok = FALSE; >> - break; >> } >> - } while ((l_iter = l_iter->next) != l_first); >> - } >> - else { >> - ok = FALSE; >> - } >> >> - if (ok == FALSE) { >> - BM_elem_flag_disable(f, BM_ELEM_SELECT); >> + if (ok == FALSE) { >> + BM_elem_flag_disable(f, >> BM_ELEM_SELECT); >> + } >> + } >> } >> } >> + /* end sections */ >> >> /* Remove any deselected elements from the BMEditSelection */ >> BM_select_history_validate(bm); >> @@ -212,32 +226,42 @@ >> >> int ok; >> >> - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { >> - if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && >> - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && >> - !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) >> + /* we can use 2 sections here because the second loop isnt checking >> edge selection */ >> +#pragma omp parallel sections >> + { >> +#pragma omp section >> { >> - BM_elem_flag_enable(e, BM_ELEM_SELECT); >> + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { >> + if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) >> && >> + BM_elem_flag_test(e->v2, BM_ELEM_SELECT) >> && >> + !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) >> + { >> + BM_elem_flag_enable(e, >> BM_ELEM_SELECT); >> + } >> + } >> } >> - } >> >> - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { >> - ok = TRUE; >> - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { >> - l_iter = l_first = BM_FACE_FIRST_LOOP(f); >> - do { >> - if (!BM_elem_flag_test(l_iter->v, >> BM_ELEM_SELECT)) { >> +#pragma omp section >> + { >> + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { >> + ok = TRUE; >> + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { >> + l_iter = l_first = >> BM_FACE_FIRST_LOOP(f); >> + do { >> + if >> (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { >> + ok = FALSE; >> + break; >> + } >> + } while ((l_iter = l_iter->next) != >> l_first); >> + } >> + else { >> ok = FALSE; >> - break; >> } >> - } while ((l_iter = l_iter->next) != l_first); >> - } >> - else { >> - ok = FALSE; >> - } >> >> - if (ok) { >> - BM_elem_flag_enable(f, BM_ELEM_SELECT); >> + if (ok) { >> + BM_elem_flag_enable(f, >> BM_ELEM_SELECT); >> + } >> + } >> } >> } >> >> @@ -810,8 +834,6 @@ >> >> const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE}; >> >> - BMIter iter; >> - BMElem *ele; >> int i; >> >> if (hflag & BM_ELEM_SELECT) { >> @@ -825,16 +847,25 @@ >> { >> /* fast path for deselect all, avoid topology loops >> * since we know all will be de-selected anyway. */ >> + >> +#pragma omp parallel for schedule(dynamic) >> for (i = 0; i < 3; i++) { >> + BMIter iter; >> + BMElem *ele; >> + >> ele = BM_iter_new(&iter, bm, iter_types[i], NULL); >> for ( ; ele; ele = BM_iter_step(&iter)) { >> BM_elem_flag_disable(ele, BM_ELEM_SELECT); >> } >> } >> + >> bm->totvertsel = bm->totedgesel = bm->totfacesel = 0; >> } >> else { >> for (i = 0; i < 3; i++) { >> + BMIter iter; >> + BMElem *ele; >> + >> if (htype & flag_types[i]) { >> ele = BM_iter_new(&iter, bm, iter_types[i], >> NULL); >> for ( ; ele; ele = BM_iter_step(&iter)) { >> >> Modified: trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c >> =================================================================== >> --- trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c 2012-12-12 >> 04:50:53 UTC (rev 52907) >> +++ trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c 2012-12-12 >> 05:04:01 UTC (rev 52908) >> @@ -63,41 +63,63 @@ >> >> void BM_mesh_elem_toolflags_ensure(BMesh *bm) >> { >> - if (bm->toolflagpool == NULL) { >> - const int totflagpool_size = max_ii(512, bm->totvert + >> bm->totedge + bm->totface); >> - BLI_mempool *toolflagpool; >> + if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) { >> + return; >> + } >> >> - BMIter iter; >> - BMElemF *ele; >> - const char iter_types[3] = {BM_VERTS_OF_MESH, >> - BM_EDGES_OF_MESH, >> - BM_FACES_OF_MESH}; >> + bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), >> max_ii(512, bm->totvert), 512, 0); >> + bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), >> max_ii(512, bm->totedge), 512, 0); >> + bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), >> max_ii(512, bm->totface), 512, 0); >> >> - int i; >> - >> - BLI_assert(bm->totflags == 0); >> - >> - /* allocate one flag pool that we don't get rid of. */ >> - toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), >> totflagpool_size, 512, 0); >> - >> - >> - for (i = 0; i < 3; i++) { >> - BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { >> +#pragma omp parallel sections >> + { >> +#pragma omp section >> + { >> + BLI_mempool *toolflagpool = bm->vtoolflagpool; >> + BMIter iter; >> + BMElemF *ele; >> + BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { >> ele->oflags = >> BLI_mempool_calloc(toolflagpool); >> } >> } >> +#pragma omp section >> + { >> + BLI_mempool *toolflagpool = bm->etoolflagpool; >> + BMIter iter; >> + BMElemF *ele; >> + BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { >> + ele->oflags = >> BLI_mempool_calloc(toolflagpool); >> + } >> + } >> +#pragma omp section >> + { >> + BLI_mempool *toolflagpool = bm->ftoolflagpool; >> + BMIter iter; >> + BMElemF *ele; >> + BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { >> >> @@ Diff output truncated at 10240 characters. @@ >> _______________________________________________ >> Bf-blender-cvs mailing list >> [email protected] >> http://lists.blender.org/mailman/listinfo/bf-blender-cvs > _______________________________________________ > Bf-committers mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-committers
Thanks for the heads up, added BM_OMP_LIMIT so we can tweak it if its giving issues on low poly meshes. -- - Campbell _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
