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:
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!
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);
}