//MEM = initial memory, INDATA, the actual floating point value
#define atomicAddFloatX(MEM, INDATA)\
{\
float data = INDATA;\
float prev_mem = uintBitsToFloat(MEM);\
float exchange_mem = prev_mem;\
float input_mem = (data + prev_mem);\ //initially this is what we assume we want to put in here.
while (true){\
uint exchange_memuint = atomicExchange(MEM, floatBitsToUint(input_mem));\ //exchange with memory location, assume other threads are doing the same exact thing. atomic exchange returns the value that was already there.
exchange_mem = uintBitsToFloat(exchange_memuint);\ //get the floating point value from returned value.
if (prev_mem != exchange_mem){\ //if it was equal to what we initially suspected, we can exit, our data is guaranteed to be in this memory location for all other threads trying to perform this function.
input_mem = exchange_mem + data;\ //otherwise we need to update our input. Another thread completed their atomic exchange before us.
prev_mem = exchange_mem;\ // update our expectation of return now.
} else {\
break;\
}\
}\
}
//example
atomicAddFloatX(output[thread_id].x, 3.0);
Vulkan supports atomic float, but only for Nvidia at the moment. It's possible however that other vendors will never support atomic float. In order to provide atomic float functionality, which is absolutely required for some algorithms, I tried my best to try to create something that would have the same effect, if less performant.
I have access to #extension GL_KHR_memory_scope_semantics, but it is unclear if that can help me or not. I think I have bugs in how I'm dealing with loading the initial memory logically, though through internal tests in projects where this is used this seems to not have errors, but that may be a fluke of the Nvidia memory model. I'm currently using this for the immersed boundary method for fluid solid coupling, its used to accumulate forces in a part of the algorithm.
I'm also not sure if there's other things I can do to speed this up, though I think this has serialized performance characteristics, which should be equivalent to atomic float normally.