views:

142

answers:

3

I have to implement an algorithm to decompose 3D volumes in voxels. The algorithm starts by identifying which vertexes is on each side of the cut plan and in a second step which edge traverse the cutting plan.

This process could be optimized by using the benefit of sorted list. Identifying the split point is O log(n). But I have to maintain one such sorted list per axis and this for vertexes and edges. Since this is to be implemented to be used by GPU I also have some constrains on memory management (i.e. CUDA). Intrusive listsM/trees and C are imposed.

With a complete "voxelization" I expect to endup with ~4000 points, and 12000 edges. Fortunately this can be optimized by using a smarter strategy to get rid of processed voxels and order residual volumes cutting to keep their number to a minimum. In this case I would expect to have less then 100 points and 300 edges. This makes the process more complex to manage but could end up beeing more efficient.

The question is thus to help me identify the criteria to determine when the benefit of using a sorted data structure is worth the effort and complexity overhead compared to simple intrusive linked lists.

+2  A: 

chmike, this really sounds like the sort of thing you want to do first the simpler way, and see how it behaves. Any sort of GPU voxelization approach is pretty fragile to system details once you get into big volumes at least (which you don't seem to have). In your shoes I'd definitely want the straightforward implementation first, if for no other reason that to check against....

simon
It is a really good idea to have a straightforward, perhaps slow version, that is correct and can be tested against. And then you can develop a more sophisticated version that will run faster and can be checked for correctness against the naïve version.Then again, making sorted linked lists is not that complicated, it is mostly about how you insert the elements, however, retrieving them in a different order than sort-order still yields slow results, as will insertion of new elements.
Tobias Wärre
I have it already and could validate the benefit of voxelization. Now I want to optimize the process and use a different strategy than the one used in the first place. In the first approach I instantiated the voxels and cut their facets with the volume surfaces. This was the most simple to implement and is trivial to parallelize. But I end up recomputing the same intersection points and other values many times. The optimization by voxelizing the volume would avoid it, but with an overhead.
chmike
+1  A: 

The question will ALWAYS boil down to which operator is most common, accessing, or adding. If you have an unordered list, adding to it takes no time, and accessing particular items takes extra time. If you have a sorted list, adding to it takes more time, but accessing it is quicker.

Most applications spending most of their time accessing the data, rather than adding to it, which means that the (running) time overhead in creating a sorted list will usually be balanced or covered by the time saved in accessing the list. If there is a lot of churn in your data (which it doesn't sound like there is) then maintaining a sorted list isn't necessarily advisable, because you will be constantly resorting the list as considerable CPU cost.

The complexity of the data structures only matters if they cannot be sorted in a useful way. If they can be sorted, then you'll have to go by the heuristic of

number of accesses:number of changes

to determine if sorting is a good idea.

You are right. For each cut I have to partition the list in two. In fact I keep one part in the list and extract elements of the other part which happens to be small in general. I then have to add a few new elements. So a tree is a bad choice. A sorted doubly linked list sounds better. I would have one list per axis. Vertex insertion can be optimized because the edge defines a range in each list. Searching insertion location of split edge insertion could start from the previous edge position.
chmike
I start to wonder if the overhead of maintaining these data structures could spoil the benefit of avoiding to recompute the same values that happens in my first solution. (see my comment to Simon's answer).
chmike
If you are 'recomputing' anything, then it would be best to create some sort of 'answer-key' table/dictionary/tree/sorted-list and reference that instead of doing recomputations.
+1  A: 

After considering all answers I found out that the later method used to avoid duplicate computation would end up being less efficient because of the effort to maintain and navigate in the data structure. Beside, the initial method is straightforward to parallelize with a few small kernel routines and thus more appropriate for GPU implementation.

Checking back my initial method I also found significant optimization opportunities that leaves the volume cut method well behind.

Since I had to pick one answer I chose devinb because he answer the question, but Simon's comment, backed up by Tobias Warre comment, were as valuable for me.

Thanks to all of you for helping me sorting out this issue. Stack overflow is an impressive service.

chmike