Re: Voxel data handling (fwd)

New Message Reply Date view Thread view Subject view Author view

From: Dave Akers (dla@engr.sgi.com)
Date: 12/07/2000 10:39:09


Hi Manfred,

  My comments are embedded below:

> Hi Dave,
>
> thanks for the interesting insight into the volumizer internals.
>
> > Interleaving is somewhat complicated. ;) By default, the API will simply
> > allocate a new array and copy the data, then free the previous two
> > pointers. However, if it sees that the two bricks being interleaved are
> > allocated from contiguous memory regions, it will attempt to perform
> > "in-place" interleaving. (The two pointers are concatenated together and
> > treated as one, minimizing fragmentation of memory.) Once the
> > volumeOptimize() method has interleaved the data, the data pointers for
> > both bricks are updated to point to the interleaved data. So it is indeed
> > possible to access the interleaved data directly.
>
> Did I get this right, also in the case of external brick data, volumizer
> deletes the old brick memory? Freeing memory that has been allocated by
> the user?
> Quite naughty ;-) You wouldn't actually expect such behaviour.
> In addition to that this is a source of severe program errors.
> What about the original pointer, the memory chunk was assigned to,
> normally a good programmer would try to free the memory adressed by
> this pointer. Volumizer also doen't know how the memory was allocated
> using ,,new'' or ,,alloc'' or whether the pointer that was given to
> a brick points to the beginning of an allocated memory block at all...
>

Yes, you did get this right. ;-) And yes, this is quite naughty. There are
certainly ways of combining the use of setDataPtr() and
textureInterleave() that will cause serious memory allocation errors.
(That's part of what I meant when I said that interleaving was
"complicated.") As I mentioned previously, I would not attempt to use
texture interleaving with external data. To achieve correct texture
interleaving using voAppearanceActions::textureInterleave(), you should
really let Volumizer have its own copy of the data by using the
dataAlloc() method for each brick, as the demos do... I'll see if there's
something I can do to clean this up a little without breaking the behavior
of existing applications.

> > The disadvantage, of course, is that you are consuming twice the memory -
> > and that you will have to make modifications to both representations every
> > time something changes. But it would allow you to take advantage of any
> > bricking strategy easily and to use texture interleaving to improve
> > performance.
> >
> > Regarding the performance of getVoxelAddr(): It is a convenience routine
> > that determines the address of a voxel given its coordinates. It must
> > correctly take into account interleaving and bricking to make this
> > determination. For applications whose performance is gated by the speed of
> > many reads of voxel data, this is not as efficient as simply performing
> > pointer arithmetic on individual bricks.
>
> The question came up from Matthias posting. He complained about the poor
> performance of using "getVoxelAddr". As I got the point this is only due
> to a little bit more of pointer arithmetic that has to be done by this
> methode compared to directly accessing the memory. And in addition to that
> getVoxelAddr first has to find the brick a voxel is contained in - which
> might impose most of the overhead I suppose ?
> So we can guess Matthias does access a lot of voxels in his
> volume modifications or otherwise he would not suffer from poor
> performance?

If he is seeing significant performance bottlenecks in getVoxelAddr(), I
would assume that he is constantly accessing voxels.. but only Matthias
knows his application well. ;-)

> For this situation you propose a copy of the volume data for fast access
> in case of voxel read and to perform voxel writes on the internal brick
> data and for consistency reasons on the external copy as well?
> For writes into brick memory you propose setVoxel()/setSubVolume()
> depending on the number of voxels that have been modified.
>

I was merely proposing keeping an external copy in case the user needed to
keep an external copy for some other reason. (Say, for example, you had an
isosurfacing library that took its input as a linear array of voxels.) You
might also want an external copy in your own format if you needed
extremely fast reads of voxel data, avoiding the interleaving and
overlapping calculations per address.

> Wouldn't it be an even better idea to perform all volume data modifications
> brick by brick. I guess voBrick::getVoxelAddr should be quite fast for
> there are much less indirections than using voBricksetCollection::getVoxelAddr
> an the pointer arithmetic of voBrick::getVoxelAddr can hardly be more
> expensive than working directly on the data array. At least it shouldn't.
> So you can save memory and perform voxel modifications in place.

If you want to custom-code your application to handle texture interleaving
and the overlapping regions between bricks, then it certainly would be
faster to perform data modifications on a brick-by-brick basis. The
convenience functions for setting voxels and subregions do this for you,
but there is some overhead involved of course.

> O.K. the method of choice will depend on what exactly you want to do
> with your volume data. Unfortunately Matthias did not go into details
> of his task.

Yep...

-Dave


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Thu Dec 07 2000 - 12:33:26 PST