[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52908] trunk/blender/source/blender: use openmp to thread some common bmesh operations

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Dec 12 06:34:02 CET 2012


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 <ideasman42 at gmail.com> 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
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs


More information about the Bf-committers mailing list