web-dev-qa-db-ja.com

なぜatomicAddがdoubleに実装されていないのですか?

DoubleのatomicAdd()がCUDA4.0以降の一部として明示的に実装されていないのはなぜですか?

CUDAプログラミングガイド4.1 の付録Fページ97から、次のバージョンのatomicAddが実装されています。

int atomicAdd(int* address, int val);
unsigned int atomicAdd(unsigned int* address,
                       unsigned int val);
unsigned long long int atomicAdd(unsigned long long int* address,
                                 unsigned long long int val);
float atomicAdd(float* address, float val)

同じページで、プロジェクトで使い始めたばかりの、doublesのatomicAddの小さな実装を次のように示しています。

__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);
}

上記のコードをCUDAの一部として定義してみませんか?

35
smilingbuddha

編集:CUDA 8の時点で、倍精度atomicAdd()がCUDAに実装され、SM_6X(Pascal)GPUでハードウェアがサポートされています。

現在、ハードウェアのatomicAddに対してdoubleをサポートするCUDAデバイスはありません。 お気づきのように、64ビット整数ではatomicCASの観点から実装できますが、それには重要なパフォーマンスコストがかかります。

したがって、CUDAソフトウェアチームは、CUDA標準ライブラリの一部にするのではなく、開発者向けのオプションとして正しい実装を文書化することを選択しました。このようにして、開発者は、理解していないパフォーマンスコストを無意識のうちに選択することはありません。

余談ですが、この質問を「建設的ではない」として閉じるべきではないと思います。 +1という完全に有効な質問だと思います。

39
harrism