5

2D テクスチャは、画像処理アプリケーションにおける CUDA の便利な機能です。ピッチ リニア メモリを 2D テクスチャにバインドするには、メモリを整列する必要があります。cudaMallocPitchアラインされたメモリ割り当てに適したオプションです。私のデバイスでは、 によって返されるピッチcudaMallocPitchは 512 の倍数です。つまり、メモリは 512 バイトにアラインされています。

デバイスの実際のアライメント要件は、cudaDeviceProp::texturePitchAlignment私のデバイスでは 32 バイトであると判断されます。

私の質問は:

cudaMallocPitch2D テクスチャの実際のアライメント要件が 32 バイトである場合、 512 バイトのアライメントされたメモリが返されるのはなぜですか?

メモリの無駄じゃない?たとえば、サイズが 513 x 100 の 8 ビット イメージを作成すると、1024 x 100 バイトを占有します。

次のシステムでこの動作が発生します。

1: Asus G53JW + Windows 8 x64 + GeForce GTX 460M + CUDA 5 + Core i7 740QM + 4GB RAM

2: Dell Inspiron N5110 + Windows 7 x64 + GeForce GT525M + CUDA 4.2 + Corei7 2630QM + 6GB RAM

4

2 に答える 2

4

これはやや推測に基づく回答ですが、割り当てのピッチがテクスチャに対して満たさなければならない2 つの配置プロパティがあることに注意してください。1 つはテクスチャ ポインタ用で、もう 1 つはテクスチャ行用です。cudaMallocPitchによって定義された前者を尊重していると思いcudaDeviceProp::textureAlignmentます。例えば:

#include <cstdio>

int main(void)
{
    const int ncases = 12;
    const size_t widths[ncases] = { 5, 10, 20, 50, 70, 90, 100,
        200, 500, 700, 900, 1000 };
    const size_t height = 10;

    float *vals[ncases];
    size_t pitches[ncases];

    struct cudaDeviceProp p;
    cudaGetDeviceProperties(&p, 0);
    fprintf(stdout, "Texture alignment = %zd bytes\n",
            p.textureAlignment);
    cudaSetDevice(0);
    cudaFree(0); // establish context

    for(int i=0; i<ncases; i++) {
        cudaMallocPitch((void **)&vals[i], &pitches[i], 
            widths[i], height);
        fprintf(stdout, "width = %zd <=> pitch = %zd \n",
                widths[i], pitches[i]);
    }

    return 0;
}

GT320M では次のようになります。

Texture alignment = 256 bytes
width = 5 <=> pitch = 256 
width = 10 <=> pitch = 256 
width = 20 <=> pitch = 256 
width = 50 <=> pitch = 256 
width = 70 <=> pitch = 256 
width = 90 <=> pitch = 256 
width = 100 <=> pitch = 256 
width = 200 <=> pitch = 256 
width = 500 <=> pitch = 512 
width = 700 <=> pitch = 768 
width = 900 <=> pitch = 1024 
width = 1000 <=> pitch = 1024 

cudaDeviceProp::texturePitchAlignmentCUDA配列にも当てはまると思います。

于 2012-09-23T10:35:47.517 に答える
3

メモリ割り当てについていくつかの実験を行った後、ついにメモリを節約する実用的なソリューションを見つけました。によって割り当てられたメモリを強制的に整列させると、完全に機能しますcudaMalloccudaBindTexture2D

cudaError_t alignedMalloc2D(void** ptr, int width, int height, int* pitch, int alignment = 32)
{       
   if((width% alignment) != 0)
      width+= (alignment - (width % alignment));

   (*pitch) = width;

   return cudaMalloc(ptr,width* height);
}

この関数によって割り当てられるメモリは、 の要件である 32 バイトにアラインされていますcudaBindTexture2D。メモリ使用量が 16 分の 1 になり、2D テクスチャを使用するすべての CUDA 関数も正しく動作しています。

以下は、現在選択されている CUDA デバイスのピッチ調整要件を取得するための小さなユーティリティ関数です。

int getCurrentDeviceTexturePitchAlignment()
{
   cudaDeviceProp prop;
   int currentDevice = 0;

   cudaGetDevice(&currentDevice);

   cudaGetDeviceProperties(&prop,currentDevice);

   return prop.texturePitchAlignment;
}
于 2012-10-09T09:54:09.797 に答える