commit c95cc1f4a73e7b0fa2ee84378fba4fc4118db209
parent 2b55715df70bf7787e057b8a16c9bcecb2dac85b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 23 Feb 2018 14:23:50 +0100
Avoid darray elts copy.
By replacing push_back by resize where possible.
Diffstat:
1 file changed, 95 insertions(+), 76 deletions(-)
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -248,13 +248,12 @@ extract_connex_components
{
res_T res = RES_OK;
medium_id_t m;
- size_t tmp;
struct senc_scene* scn;
struct mem_allocator* alloc;
struct darray_side_id stack;
/* Id of the first trgside not already in a connex component */
side_id_t first_side_not_in_component = 0;
- struct cc_descriptor current_cc;
+ struct cc_descriptor* current_cc;
ASSERT(trgsides && desc && connex_components && triangles_tmp_array);
@@ -264,32 +263,31 @@ extract_connex_components
/* Init stack */
darray_side_id_init(alloc, &stack);
- /* Extract connex components until every side is involved */
- cc_descriptor_init(alloc, ¤t_cc);
for(;;) {
/* Any not-already-used side is used as a starting point */
const side_id_t start_side_id = get_side_not_in_connex_component(scn,
trgsides, &first_side_not_in_component);
side_id_t crt_side_id = start_side_id;
char* side_membership;
+ size_t sz;
ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nutris);
if(start_side_id == SIDE_NULL__)
break; /* start_side_id=SIDE_NULL__ => done! */
ASSERT(trgsides[start_side_id].list_id == FLAG_LIST_SIDE_LIST);
- m = trgsides[start_side_id].medium;
-
- /* Reset CC data for a new CC */
- tmp = darray_cc_descriptor_size_get(connex_components);
- ASSERT(tmp <= COMPONENT_MAX__);
- cc_descriptor_clear(¤t_cc);
+ /* Create and init a new component */
+ sz = darray_cc_descriptor_size_get(connex_components);
+ OK(darray_cc_descriptor_resize(connex_components, 1+ sz));
+ current_cc = darray_cc_descriptor_data_get(connex_components) + sz;
/* 1 char per triangle (2 sides) */
- darray_char_resize(¤t_cc.side_membership, scn->nutris);
- side_membership = darray_char_data_get(¤t_cc.side_membership);
+ OK(darray_char_resize(¤t_cc->side_membership, scn->nutris));
+ side_membership = darray_char_data_get(¤t_cc->side_membership);
memset(side_membership, 0, scn->nutris * sizeof(char));
- current_cc.cc_id = (component_id_t)tmp;
- current_cc.medium = m;
+ m = trgsides[start_side_id].medium;
+ ASSERT(sz <= COMPONENT_MAX__);
+ current_cc->cc_id = (component_id_t)sz;
+ current_cc->medium = m;
for(;;) {
int i;
@@ -302,21 +300,21 @@ extract_connex_components
ASSERT(trgsides[crt_side_id].medium == m);
/* Record crt_side both as component and triangle level */
- current_cc.side_count++;
+ current_cc->side_count++;
trgsides[crt_side_id].list_id = FLAG_LIST_COMPONENT;
if(TRGSIDE_IS_FRONT(crt_side_id)) {
ASSERT(trg_comp->component[SIDE_FRONT] == USHRT_MAX);
- trg_comp->component[SIDE_FRONT] = current_cc.cc_id;
+ trg_comp->component[SIDE_FRONT] = current_cc->cc_id;
ASSERT(!(side_membership[crt_trg_id] & FLAG_FRONT));
side_membership[crt_trg_id] |= FLAG_FRONT;
} else {
ASSERT(trg_comp->component[SIDE_BACK] == USHRT_MAX);
- trg_comp->component[SIDE_BACK] = current_cc.cc_id;
+ trg_comp->component[SIDE_BACK] = current_cc->cc_id;
ASSERT(!(side_membership[crt_trg_id] & FLAG_BACK));
side_membership[crt_trg_id] |= FLAG_BACK;
}
#ifndef NDEBUG
- crt_side->member_of_cc = current_cc.cc_id;
+ crt_side->member_of_cc = current_cc->cc_id;
#endif
/* Store neighbour sides in a waiting stack */
FOR_EACH(i, 0, 3) {
@@ -351,13 +349,12 @@ extract_connex_components
log_err(desc->scene->dev, "Media: %lu VS %lu\n",
neighbour->medium, crt_side->medium);
res = RES_BAD_ARG;
- cc_descriptor_release(¤t_cc);
goto error;
}
if(neighbour->list_id == FLAG_LIST_COMPONENT) {
/* Already processed */
#ifndef NDEBUG
- ASSERT(neighbour->member_of_cc == current_cc.cc_id);
+ ASSERT(neighbour->member_of_cc == current_cc->cc_id);
#endif
continue;
}
@@ -371,10 +368,8 @@ extract_connex_components
crt_side_id = get_side_from_stack(trgsides, &stack);
}
/* Keep track of this new connex component */
- find_component_Zmax(scn, triangles_tmp_array, ¤t_cc);
- darray_cc_descriptor_push_back(connex_components, ¤t_cc);
+ find_component_Zmax(scn, triangles_tmp_array, current_cc);
}
- cc_descriptor_release(¤t_cc);
exit:
darray_side_id_release(&stack);
@@ -667,7 +662,7 @@ scan_edges
ASSERT((size_t)scn->nuverts + (size_t)scn->nutris + 2 <= EDGE_MAX__);
/* Make some room for edges. */
- max_nbedges = (edge_id_t)(scn->nuverts + scn->nutris + 2);
+ max_nbedges = (edge_id_t)(scn->nuverts + scn->nutris + 4);
htable_edge_id_init(scn->dev->allocator, &edge_ids);
OK(htable_edge_id_reserve(&edge_ids, max_nbedges));
OK(darray_neighbourhood_reserve(neighbourhood_by_edge, max_nbedges));
@@ -678,40 +673,50 @@ scan_edges
triangles_tmp = darray_triangle_tmp_data_get(triangles_tmp_array);
ASSERT(scn->nutris == darray_triangle_tmp_size_get(triangles_tmp_array));
FOR_EACH(t, 0, scn->nutris) {
- struct darray_neighbour* neighbour_list;
- struct neighbour_info neighbour;
- struct edge_neighbourhood neighbourhood;
+ struct trg_edge edge;
char e;
FOR_EACH(e, 0, 3) {
edge_id_t* p_id;
- edge_id_t id;
-
/* Create edge. */
set_edge(triangles_in[t].vertice_id[e],
- triangles_in[t].vertice_id[(e + 1) % 3],
- &neighbourhood.edge, &triangles_tmp[t].reversed_edge[e]);
+ triangles_in[t].vertice_id[(e + 1) % 3], &edge, &triangles_tmp[t].reversed_edge[e]);
/* Find edge id; create it if not already done. */
- p_id = htable_edge_id_find(&edge_ids, &neighbourhood.edge);
+ p_id = htable_edge_id_find(&edge_ids, &edge);
if(p_id) {
- id = *p_id;
+ struct edge_neighbourhood* n =
+ darray_neighbourhood_data_get(neighbourhood_by_edge) + *p_id;
+ struct neighbour_info* info;
+ size_t sz;
+ /* Add neighbour info to existing edge's neighbour list */
+ ASSERT(n->edge.vrtx0 == edge.vrtx0 && n->edge.vrtx1 == edge.vrtx1);
+ sz = darray_neighbour_size_get(&n->neighbours);
+ OK(darray_neighbour_resize(&n->neighbours, 1 + sz));
+ info = darray_neighbour_data_get(&n->neighbours) + sz;
+ info->trg_id = t;
+ info->edge_rank = e;
} else {
/* Create id */
- size_t tmp;
- tmp = htable_edge_id_size_get(&edge_ids);
- ASSERT(tmp <= EDGE_MAX__);
- id = (edge_id_t)tmp;
- OK(htable_edge_id_set(&edge_ids, &neighbourhood.edge, &id));
- darray_neighbour_init(scn->dev->allocator, &neighbourhood.neighbours);
- OK(darray_neighbourhood_push_back(neighbourhood_by_edge,
- &neighbourhood));
+ edge_id_t id;
+ struct edge_neighbourhood* n;
+ struct neighbour_info* info;
+ size_t sz = htable_edge_id_size_get(&edge_ids);
+ ASSERT(sz <= EDGE_MAX__);
+ id = (edge_id_t) sz;
+ ASSERT(htable_edge_id_size_get(&edge_ids)
+ == darray_neighbourhood_size_get(neighbourhood_by_edge));
+ OK(htable_edge_id_set(&edge_ids, &edge, &id));
+ OK(darray_neighbourhood_resize(neighbourhood_by_edge, 1 + sz));
+ n = darray_neighbourhood_data_get(neighbourhood_by_edge) + sz;
+ /* Add neighbour info to a newly created edge's neighbour list */
+ n->edge = edge;
+ ASSERT(darray_neighbour_size_get(&n->neighbours) == 0);
+ OK(darray_neighbour_reserve(&n->neighbours, 2));
+ OK(darray_neighbour_resize(&n->neighbours, 1));
+ info = darray_neighbour_data_get(&n->neighbours);
+ info->trg_id = t;
+ info->edge_rank = e;
}
- /* Add neighbour info to edge's neighbour list */
- neighbour_list
- = &darray_neighbourhood_data_get(neighbourhood_by_edge)[id].neighbours;
- neighbour.trg_id = t;
- neighbour.edge_rank = e;
- darray_neighbour_push_back(neighbour_list, &neighbour);
}
}
@@ -744,14 +749,14 @@ collect_and_link_neighbours
/* Htable used to give an id to edges */
struct htable_edge_id edge_ids;
res_T res = RES_OK;
-
ASSERT(scn && trgsides && triangles_tmp_array);
ASSERT((size_t) scn->nuverts + (size_t) scn->nutris + 2 <= EDGE_MAX__);
darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge);
/* Make some room for edges. */
- approx_nbedges = (edge_id_t) ((scn->nuverts + scn->nutris) / num_thread);
+ approx_nbedges = 4 + (num_thread == 1 ? (edge_id_t)(scn->nuverts + scn->nutris)
+ : (edge_id_t)((scn->nuverts + scn->nutris + num_thread) / (0.75 * num_thread)));
htable_edge_id_init(scn->dev->allocator, &edge_ids);
OK(htable_edge_id_reserve(&edge_ids, approx_nbedges));
OK(darray_neighbourhood_reserve(&neighbourhood_by_edge, approx_nbedges));
@@ -760,42 +765,57 @@ collect_and_link_neighbours
triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in);
triangles_tmp = darray_triangle_tmp_data_get(triangles_tmp_array);
ASSERT(scn->nutris == darray_triangle_tmp_size_get(triangles_tmp_array));
+
FOR_EACH(t, 0, scn->nutris) {
- struct darray_neighbour* neighbour_list;
- struct neighbour_info neighbour;
- struct edge_neighbourhood neighbourhood;
+ struct trg_edge edge;
char ee;
+ ASSERT(t < scn->nutris);
FOR_EACH(ee, 0, 3) {
edge_id_t* p_id;
- edge_id_t id;
const vrtx_id_t v0 = triangles_in[t].vertice_id[ee];
const vrtx_id_t v1 = triangles_in[t].vertice_id[(ee + 1) % 3];
/* Process only "my" edges! */
const int h = v0 + v1 + MMIN(v0,v1); /* v0,v1 and v1,v0 must give the same hash!!! */
if (h % num_thread != rank) continue;
/* Create edge. */
- set_edge(v0, v1, &neighbourhood.edge, &triangles_tmp[t].reversed_edge[ee]);
+ set_edge(v0, v1, &edge, &triangles_tmp[t].reversed_edge[ee]);
/* Find edge id; create it if not already done. */
- p_id = htable_edge_id_find(&edge_ids, &neighbourhood.edge);
+ p_id = htable_edge_id_find(&edge_ids, &edge);
if (p_id) {
- id = *p_id;
+ struct edge_neighbourhood* n =
+ darray_neighbourhood_data_get(&neighbourhood_by_edge) + *p_id;
+ struct neighbour_info* info;
+ size_t sz;
+ /* Add neighbour info to existing edge's neighbour list */
+ ASSERT(n->edge.vrtx0 == edge.vrtx0 && n->edge.vrtx1 == edge.vrtx1);
+ sz = darray_neighbour_size_get(&n->neighbours);
+ OK(darray_neighbour_resize(&n->neighbours, 1 + sz));
+ info = darray_neighbour_data_get(&n->neighbours) + sz;
+ info->trg_id = t;
+ info->edge_rank = ee;
}
else {
/* Create id */
- tmp = htable_edge_id_size_get(&edge_ids);
- ASSERT(tmp <= EDGE_MAX__);
- id = (edge_id_t)tmp;
- OK(htable_edge_id_set(&edge_ids, &neighbourhood.edge, &id));
- darray_neighbour_init(scn->dev->allocator, &neighbourhood.neighbours);
- OK(darray_neighbourhood_push_back(&neighbourhood_by_edge,
- &neighbourhood));
+ edge_id_t id;
+ struct edge_neighbourhood* n;
+ struct neighbour_info* info;
+ size_t sz = htable_edge_id_size_get(&edge_ids);
+ ASSERT(sz <= EDGE_MAX__);
+ id = (edge_id_t)sz;
+ ASSERT(htable_edge_id_size_get(&edge_ids)
+ == darray_neighbourhood_size_get(&neighbourhood_by_edge));
+ OK(htable_edge_id_set(&edge_ids, &edge, &id));
+ OK(darray_neighbourhood_resize(&neighbourhood_by_edge, 1 + sz));
+ n = darray_neighbourhood_data_get(&neighbourhood_by_edge) + sz;
+ /* Add neighbour info to a newly created edge's neighbour list */
+ n->edge = edge;
+ ASSERT(darray_neighbour_size_get(&n->neighbours) == 0);
+ OK(darray_neighbour_reserve(&n->neighbours, 2));
+ OK(darray_neighbour_resize(&n->neighbours, 1));
+ info = darray_neighbour_data_get(&n->neighbours);
+ info->trg_id = t;
+ info->edge_rank = ee;
}
- /* Add neighbour info to edge's neighbour list */
- neighbour_list
- = &darray_neighbourhood_data_get(&neighbourhood_by_edge)[id].neighbours;
- neighbour.trg_id = t;
- neighbour.edge_rank = ee;
- darray_neighbour_push_back(neighbour_list, &neighbour);
}
}
@@ -1073,7 +1093,7 @@ build_result
size_t tmp;
component_id_t cc_count, c;
enclosure_id_t e;
- side_id_t* side_counts;
+ side_id_t* side_counts = NULL;
ASSERT(desc && connex_components);
@@ -1082,7 +1102,7 @@ build_result
ASSERT(tmp < COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
cc_descriptors = darray_cc_descriptor_cdata_get(connex_components);
- darray_enclosure_resize(&desc->enclosures, desc->enclosures_count);
+ OK(darray_enclosure_resize(&desc->enclosures, desc->enclosures_count));
enclosures = darray_enclosure_data_get(&desc->enclosures);
triangles_in = darray_triangle_in_cdata_get(&desc->scene->triangles_in);
/* Set some enclosure data */
@@ -1114,8 +1134,7 @@ build_result
res = RES_MEM_ERR;
goto error;
}
- res = darray_triangle_enc_resize(&desc->triangles_enc, desc->scene->nutris);
- if(res != RES_OK) goto error;
+ OK(darray_triangle_enc_resize(&desc->triangles_enc, desc->scene->nutris));
triangles_enc = darray_triangle_enc_data_get(&desc->triangles_enc);
htable_vrtx_id_init(alloc, &vtable);
FOR_EACH(e, 0, desc->enclosures_count) {
@@ -1259,12 +1278,10 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc)
darray_triangle_tmp_init(scn->dev->allocator, &triangles_tmp);
triangles_tmp_initialized = 1;
- darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge);
- neighbourhood_by_edge_initialized = 1;
-#ifdef PARALLEL_EDGES
+#ifndef PARALLEL_EDGES
OK(darray_triangle_tmp_resize(&triangles_tmp, scn->nutris));
trgsides
@@ -1287,6 +1304,8 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc)
#else
+ darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge);
+ neighbourhood_by_edge_initialized = 1;
/* Step 1: list edges and connect triangles to edges */
res = scan_edges(scn, &neighbourhood_by_edge, &triangles_tmp);