//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 поддерживает атомарное плавание, но только для Nvidia на данный момент. Однако возможно, что другие поставщики никогда не будут поддерживать атомарное плавание. Чтобы обеспечить атомарную функциональность с плавающей запятой, которая абсолютно необходима для некоторых алгоритмов, я изо всех сил пытался создать что-то, что имело бы тот же эффект, но менее производительно.
У меня есть доступ к #extension GL_KHR_memory_scope_semantics, но неясно, поможет ли это мне или нет. Я думаю, что у меня есть ошибки в том, как я занимаюсь логической загрузкой начальной памяти, хотя при внутренних тестах в проектах, где она используется, кажется, что ошибок нет, но это может быть случайностью модели памяти Nvidia. В настоящее время я использую это для метода погруженных границ для сцепления жидкости и твердого тела, он используется для накопления сил в части алгоритма.
Я также не уверен, могу ли я что-то сделать, чтобы ускорить это, хотя я думаю, что это имеет сериализованные характеристики производительности, которые обычно должны быть эквивалентны атомарному плаванию.