グローバルメモリの最大サイズは、__device__ __manged__
を使用して静的に割り当てられても、cudaMalloc
を使用して動的に割り当てられる場合でもGPUデバイスによってのみ制限されるべきだと考えました。cudaで静的に割り当てられたメモリを使用する場合のグローバルデバイスのメモリサイズ制限
しかし、私は__device__ manged__
方法を使用している場合、私は宣言することができる最大のアレイサイズは、GPUデバイス限界よりはるかに小さいことを見出しました。次のように
最小限の作業例は次のとおりです。
#include <stdio.h>
#include <cuda_runtime.h>
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
#define MX 64
#define MY 64
#define MZ 64
#define NX 64
#define NY 64
#define M (MX * MY * MZ)
__device__ __managed__ float A[NY][NX][M];
__device__ __managed__ float B[NY][NX][M];
__global__ void swapAB()
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
for(int j = 0; j < NY; j++)
for(int i = 0; i < NX; i++)
A[j][i][tid] = B[j][i][tid];
}
int main()
{
swapAB<<<M/256,256>>>();
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
return 0;
}
それは64 ^5 * 2 * 4/2^30 GB = 8 GB
グローバルメモリを使用し、私は、コンパイルを実行し、12ギガバイトグローバルメモリを持つNVIDIAのテスラK40cのGPU上で実行されます。
コンパイラCMD:
nvcc test.cu -gencode arch=compute_30,code=sm_30
出力警告:
warning: overflow in implicit constant conversion.
私は生成された実行ファイルを実行し、エラーが言う:驚くべきことに
GPUassert: an illegal memory access was encountered test.cu
、私は動的に割り当てを使用する場合cudaMalloc
APIを使用して同じサイズ(8GB)のグローバルメモリを使用する代わりに、com警告とランタイムエラーが発生しました。
CUDAの静的グローバルデバイスメモリの割り当て可能なサイズに関する特別な制限がある場合、私は思ったんだけど。
ありがとうございます!
PS:OSとCUDA:CentOSの6.5 x64の、CUDA-7.5。
そうだね、スタティックメモリは最大2GB制限されています。私はこれをバグとして上げようとします。ところで、私が静的に宣言した多次元配列を使用する理由は、それらが多次元物理モデリングコードの方がはるかに効率的であることがわかったからです。 1Dダイナミックに割り当てられた配列を使用すると、3Dステンシルのデータ要素を扱う際に、多くの整数演算が展開されます。 – Fred
私はCUDA 8.0 RCを試しましたが、バグはまだあります。 :( – Fred