3

CUDAプログラミングガイドには、「経由で割り当てられたメモリmalloc()はランタイムを使用して(つまり、デバイスメモリから任意のコピーメモリ関数を呼び出すことで)コピーできる」と記載されていますが、どういうわけかこの機能を再現するのに問題があります。コード:

#include <cstdio>
__device__ int* p;

__global__ void allocate_p() {
  p = (int*) malloc(10);
  printf("p = %p  (seen by GPU)\n", p);
}

int main() {
  cudaError_t err;
  int* localp = (int*) malloc(10);

  allocate_p<<<1,1>>>();
  cudaDeviceSynchronize();

  //Getting pointer to device-allocated memory
  int* tmpp = NULL;
  cudaMemcpyFromSymbol(&tmpp, p, 4);
  printf("p = %p  (seen by CPU)\n", tmpp);

  //cudaMalloc((void**)&tmpp, 40);
  err = cudaMemcpy(tmpp, localp, 40, cudaMemcpyHostToDevice);
  cudaDeviceSynchronize();
  printf(" err:%i %s", (int)err, cudaGetErrorString(err));

  delete localp;
  return 0;
}

出力でクラッシュします:

p = 0x601f920  (seen by GPU)
p = 0x601f920  (seen by CPU)
 err:11 invalid argument

私は、ホストがデバイス上の適切なアドレスを認識しているが、どういうわけかそれがから来るのを好まないことを収集しますmalloc()

以前に割り当ててから、 (ではなく)に割り当てられるカーネルへの引数としてcudaMalloc((void**)&np, 40);ポインタを渡すと、コードは正常に実行されます。npallocate_ppmalloc()

何が間違っていますか/malloc()ホスト側の機能で割り当てられたデバイスメモリをどのように使用しますか?

4

1 に答える 1

3

私の知る限り、ホストAPI関数を使用してランタイムヒープメモリをコピーすることはできません。確かにCUDA4.xでは不可能であり、CUDA5.0リリース候補はこれを変更していません。私が提供できる唯一の回避策は、カーネルを使用して最終結果を「収集」し、APIを介してまたはホストから直接アクセスできるデバイス転送バッファーまたはゼロコピーメモリにそれらを詰め込むことです。この回答と、NVIDIAのMark Harrisが、これがCUDAランタイムでの(当時の)現在の実装の制限であることを確認した別の質問で、このアプローチの例を見ることができます。

于 2012-09-03T16:02:35.167 に答える