Fix T41193: 2.71 use 100% of CPU at sculpt

Issue wascaused by the famous OpenMP crap in MSVC2013,
so only way is to use openmp threading if number of BVH
nodes is high enough.

Made it 8 for now, which seems to work rather fine on my
laptop and adult dragon from sintel. But maybe it's to be
adjusted a bit more.
This commit is contained in:
Sergey Sharybin
2014-07-28 15:47:32 +06:00
parent 82ceab593c
commit 115458b53e
5 changed files with 46 additions and 32 deletions

View File

@@ -50,6 +50,13 @@
#define STACK_FIXED_DEPTH 100
/* Setting zero so we can catch bugs in OpenMP/PBVH. */
#ifdef DEBUG
# define PBVH_OMP_LIMIT 0
#else
# define PBVH_OMP_LIMIT 8
#endif
typedef struct PBVHStack {
PBVHNode *node;
int revisiting;
@@ -965,7 +972,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
* can only update vertices marked with ME_VERT_PBVH_UPDATE.
*/
#pragma omp parallel for private(n) schedule(static)
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHNode *node = nodes[n];
@@ -1009,7 +1016,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
}
}
#pragma omp parallel for private(n) schedule(static)
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHNode *node = nodes[n];
@@ -1046,7 +1053,7 @@ void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
int n;
/* update BB, redraw flag */
#pragma omp parallel for private(n) schedule(static)
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHNode *node = nodes[n];

View File

@@ -115,7 +115,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
sculpt_undo_push_begin("Mask flood fill");
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
@@ -236,7 +236,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
bool any_masked = false;
@@ -385,7 +385,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
/* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */
BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
bool any_masked = false;

View File

@@ -396,7 +396,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
* entries might be inserted by sculpt_undo_push_node() into the
* GHash used internally by BM_log_original_vert_co() by a
* different thread. [#33787] */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP && !ss->bm)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && !ss->bm && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
SculptUndoNode *unode;
SculptUndoType type = (brush->sculpt_tool == SCULPT_TOOL_MASK ?
@@ -996,7 +996,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
zero_v3(an);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1602,7 +1602,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
for (iteration = 0; iteration <= count; ++iteration) {
float strength = (iteration != count) ? 1.0f : last;
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
switch (type) {
case PBVH_GRIDS:
@@ -1638,7 +1638,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
int n;
/* threaded loop over nodes */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1691,7 +1691,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
mul_v3_fl(offset, bstrength);
/* threaded loop over nodes */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1746,7 +1746,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
if (brush->sculpt_tool == SCULPT_TOOL_BLOB) flippedbstrength *= -1.0f;
/* threaded loop over nodes */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1789,7 +1789,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
float bstrength = ss->cache->bstrength;
int n;
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1836,7 +1836,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm);
}
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1884,7 +1884,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1932,7 +1932,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm);
}
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -1972,7 +1972,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2015,7 +2015,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 };
float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2068,7 +2068,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
mul_v3_v3v3(offset, ss->cache->scale, ss->cache->sculpt_normal_symm);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2131,7 +2131,7 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
float bstrength = ss->cache->bstrength;
int n;
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2176,7 +2176,7 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
zero_v3(fc);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2283,7 +2283,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
/* for flatten center */
zero_v3(fc);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2535,7 +2535,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
mul_v3_fl(temp, displace);
add_v3_v3(fc, temp);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2607,7 +2607,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
/* add_v3_v3v3(p, ss->cache->location, an); */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2708,7 +2708,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
mul_m4_m4m4(tmat, mat, scale);
invert_m4_m4(mat, tmat);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2772,7 +2772,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
mul_v3_fl(temp, displace);
add_v3_v3(fc, temp);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2836,7 +2836,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
mul_v3_fl(temp, displace);
add_v3_v3(fc, temp);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -2890,7 +2890,7 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl
mul_v3_fl(offset, bstrength);
/* threaded loop over nodes */
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
@@ -3059,7 +3059,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
if (totnode) {
float location[3];
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
sculpt_undo_push_node(ob, nodes[n],
brush->sculpt_tool == SCULPT_TOOL_MASK ?
@@ -3192,7 +3192,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
const bool use_orco = ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB,
SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
PBVHProxyNode *proxies;
@@ -3285,7 +3285,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;

View File

@@ -130,4 +130,11 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
void sculpt_update_object_bounding_box(struct Object *ob);
/* Setting zero so we can catch bugs in OpenMP/sculpt. */
#ifdef DEBUG
# define SCULPT_OMP_LIMIT 0
#else
# define SCULPT_OMP_LIMIT 8
#endif
#endif

View File

@@ -291,7 +291,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT)
for (i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_redraw(nodes[i]);
}