MarkB wrote:So then in my first algorithm the second flush() is not necessary?
Sorry but my bad understanding, but I can't understand why the flush() directive actually works. If the second flush() is inside a critical region, this means that that region will be executed secuetially by all threads and until one thread does not end, the next will not starts, so when flush() in invoked inside the region, the flushed variable will be updated and the new adopted value will be written in global memory. Then the next thread could read the correct value.
I think you are right, but maybe not for the correct reason!
There is an implied flush of all shared variables at the exit of the critical region, so that makes the second flush redundant.
Flush does two things: it ensures that all previous writes get committed to memory, and also that all subsequent reads come from memory. The first flush is necessary to make sure that the subsequent read of avanti really does come from memory, and not from that threads temporary view of memory (e.g. a CPU register).
In any case, this shows just how difficult reasoning about flush really is, and therefore why it is much better not to use it!