cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

foofel
Journeyman III

reusing variables

Hi, i am currently starting to experiment with opencl and found a (for me) strange behavior.  If i try to jump through a 1D Buffer, and reuse variables, i get wrong values.

An Example:

__global uint *root = octree;
uint nodeSize = GetNodeSize(root);
uint nodeNumber = 0;

/* get L1 child node */
uint childOffset = root[0];
__global uint *node = root + (childOffset * nodeSize) + (nodeNumber * nodeSize);

/* get L2 child node */
childOffset = node[0];
*node = root + (childOffset * nodeSize) + (nodeNumber * nodeSize);

 

If i try to read the value from childOffset after the last line (*node = root + ...), its 255. if i comment the last line out, it is 9 as expected (in my memory layout). But how is the last line changing a value in childOffset? (Btw. why do i get a build error for // comments in kernels? :/)

 

If I use different variable names  names for each "step" i also get the right result (just continued for the next levels)

uint childOffset3 = node2[0];
  __global uint *node3 = root + (childOffset3 * nodeSize) + (nodeNumber * nodeSize);

  /* get L4 child node */ 
uint childOffset4 = node3[0];
__global uint *node4 = root + (childOffset4 * nodeSize) + (nodeNumber * nodeSize);

 If i now access childOffset1 - childOffset4 i have the right values. Any idead of what kind of stupid error i did?

 

Thanks

 

 

0 Likes
4 Replies
malcolm3141
Journeyman III

I would guess the issue is aliasing. The childOffset variable aliases both the root[0] memory and the node[0] memory.

I believe that the default optimisations in most OpenCL compilers assume no aliasing. You can probably get around this issue using a memory barrier between the last two lines (between the read and write). Otherwise, just try not to alias the pointers, or enable strict aliasing with a compiler option.

 

Malcolm

 

0 Likes

Hey, thanks for your idea but unfortunately it didn't work. Maybe i need to think about another approach if this doesn't fit with the way opencl works.

0 Likes

Try sticking a memory fence between childOsset = node[0] and *node = root...

Looking at your code it looks like you intended node = without the *? You've not updated node, you've set the value in the tree at address node. So given the difference between that and the very last line I think you have a bug in your code anyway, though that doesn't immediately explain the problem.

This write will change the value of childOffset IF childOffset = node[0] is performed AFTER the write to node. In the absense of a memory fence and given the relaxed memory consistency model of OpenCL this is probably a valid compiler transformation. If you put a memory fence in there you guarantee that the compiler won't reorder across it and the read should be performed before the write. It would be worth checking the memory consistency model if the fences fixes it for you to see if this is right.

 

 

 

ETA: malcolm basically said the fence thing. I should read more carefully before I post.

0 Likes

Originally posted by: LeeHowes ...Looking at your code it looks like you intended node = without the *? You've not updated node, you've set the value in the tree at address node. So given the difference between that and the very last line I think you have a bug in your code anyway,...


Thanks, it works! Sometimes I am just blind

0 Likes