A Question about C++11 relaxed atomics

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Tassos Souris
    New Member
    • Aug 2008
    • 152

    A Question about C++11 relaxed atomics

    Hello there...

    Let's say i have some threads that want to give each other some non-zero values. Repeatedly in turns; that is, thread A gives thread B some non-zero value and then A responds with some non-zero value as well and this continues indefenitely. (but with more threads in chain). I use a variant of the static tree barrier for this purpose, but instead of a boolean sense value (where thread spin waiting for it to change), i use an atomic<int> initialized to zero and the thread waits until it gets a nonzero value. I use a fan-in and fan-out of 2. In particular i use the barrier to perform a min-reduction (the values exchanged are the minimum so far). Here is some code:

    Code:
    struct node{
        atomic<int> sense{0};
        atomic<int> left_child_sense{0};
        atomic<int> right_child_sense{0};
    };
    
    node nodes[1...n];
    
    void barrier_like_stuff(int my_value){
        node& my_node = nodes[my_id()];
     
        // wait until i get the values from my 2 children
        int t1, t2;
    
        while ((t1 = my_node.left_child_sense.load(relaxed)) == 0){}
        while ((t2 = my_node.right_child_sense.load(relaxed)) == 0){}
    
        // so the minimum is:
        int local_minimum = min(my_value, t1, t2);
    
        // and re-initialize for the next time
        my_node.left_child_sense.store(0, relaxed);
        my_node.right_child_sense.store(0, relaxed);
    
        // notify parent (if we have) (WHICH is either left or right)
        nodes[my_parent()].WHICH_child_sense.store(local_minimum, relaxed);
    
        // wait until my parent (if we have) passes me the final minimum value
        while ((local_minimum = my_node.sense.load(relaxed)) == 0){}
    
        // re-initialize for next time
        my_node.sense.store(0, relaxed);
    
        // and pass this minimum value to my children
        nodes[my_left_child].sense.store(local_minimum, relaxed);
        nodes[my_right_child].sense.store(local_minimum, relaxed);
    }
    This code is correct with relaxed atomics right? Because when i read a non-zero value with load(relaxed) i do not have another requirement for memory visibility from the other thread that passes my that value... (or i am wrong?). Another way to see it is that the modification order for each sense value individual does the right thing. Am i correct? Thanks for your time!
Working...