0

gcc 4.6を使用してubuntu 12.10でCUDA 5.0とGTX 670を使用しており、Gridというクラスを作成しました。

https://github.com/benadler/octocopter/blob/master/basestation/grid.cu

https://github.com/benadler/octocopter/blob/master/basestation/grid.cuh

Grid クラスは、他の 2 つのクラスで使用されています。

  • ポイントクラウドクーダ
  • 粒子システム

ここで、異なるグリッド (異なる値を持つ異なるグリッド オブジェクト) を使用する場合でも、pointcloudcuda とparticlesystem の両方のカーネルで Grid の (非静的) メソッドを使用したいと考えています。したがって、Grid を使用するすべてのクラスについて、次の 2 つの選択肢があります。

1) 私は単純にそうする

Grid hostGrid(...);
cudaMalloc(gridOnDeviceGlobal, sizeof(Grid))
cudaMemcpy(gridOnDeviceGlobal, &hostGrid, sizeof(Grid), cudaMemcpyHostToDevice)
cloudKernel<<< numBlocks, numThreads >>>(someDate, gridOnDeviceGlobal);

これは簡単ですが、カーネルはグローバル メモリからグリッド値を読み取る必要があります。これは遅いかもしれません。

2) グリッド値はめったに変わらないので、

__constant__ Grid myGridForPointCloudCuda

pointcloudcuda.cu に、2 つの関数とともに

void copyParametersToGpu(Grid *hostGrid)
{
    cudaMemcpyToSymbolAsync(myGridForPointCloudCuda, hostGrid, sizeof(Grid))
}

void getDevicePointerOfGridForPointCloudCuda(Grid** ptr)
{
    cudaGetSymbolAddress((void**)ptr, myGridForPointCloudCuda);
}

これで、pointcloudcuda.cpp で、次のことができます。

Grid hostGrid(...);
copyParametersToGpu(&hostGrid);
Grid* gridOnDeviceConstant;
getDevicePointerOfGridForPointCloudCuda(&gridOnDeviceConstant);
cloudKernel<<< numBlocks, numThreads >>>(someDate, gridOnDeviceConstant);

私の考えでは、2) の利点は、カーネル内の定数メモリへのアクセスが高速になることです。ただし、他の場所では、CUDAカーネルをコンパイルするコンパイラーは、渡されるグリッドポインターがグローバルメモリまたは定数メモリのどちらを指しているかをコンパイル時に認識しないため、これが機能しないことを読みました。メモリフェッチ命令。

Geforce GTX 670 では、2) は 1) よりも高速ですか?

私がやりたいことをするためのより良い方法はありますか?異なるグリッド インスタンスをカーネルに渡すだけです。そして、複数の Grid インスタンスを使い始める前は、定数変数は快適かつ迅速な選択でした。

ありがとう!

4

1 に答える 1

1

複数の Grid インスタンスがある場合は、単純に Grid 配列を定数メモリに割り当てるよりも、Grid インスタンスを配列にコピーし、カーネルを呼び出すときに、特定の Grid インスタンスへのポインターではなく、インデックスを Grid 配列に渡します。カーネル内では、インデックスを使用して特定のグリッド インスタンスにアクセスします。

于 2013-02-28T21:13:36.937 に答える