8
私はGPUでプロジェクトをやっていますが、cudaはdoubleをサポートしていないため、atomicAdd()をdoubleに使う必要があります。 。atomicAdd()for double for GPU
__device__ double atomicAdd(double* address, double val)
{
unsigned long long int* address_as_ull =
(unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed,
__double_as_longlong(val +
__longlong_as_double(assumed)));
} while (assumed != old);
return __longlong_as_double(old);
}
は今、私は実装がアトミックに実行することができない負荷を、必要とするので、基本的に
ありがとうございました!あなたはロード操作が仮定されている=古い、原子的でないことを意味するので、アトミック関数old = atomicCAS(address_as_ull、仮定、__ double_as_long(val + __ longlong_as_double(仮定)))変更する必要があります。また、add()は再度行う必要があります。 – taoyuanjl
いいえ、 'old'はスレッドローカル変数です。ローカルスレッドがそれを変更しない限り、その値は変更されません。変更できる唯一の値は、スレッド制御の外側では '* address'です。操作中に別のスレッドによって変更された場合、 'atomicCAS'呼び出しを繰り返す必要があります。そうでない場合、更新は行われません。 – talonmies
私はそれを持って、ループの機能は、* address_as_ullの変更の現在の値が現在のスレッドによって行われることを保証します。 – taoyuanjl