-1

現在、Quadro 400 と Tesla C2075 の 2 つの cuda 対応 GPU を搭載したサーバーで作業しています。単純なベクトル加算テスト プログラムを作成しました。私の問題は、Tesla C2075 GPU が Quadro 400 よりも強力であると考えられている一方で、仕事をするのにより多くの時間がかかることです. cudaMemcpy が実行時間のほとんどを占めており、より強力な GPU では動作が遅くなることがわかりました。ソースは次のとおりです。

void get_matrix(float* arr1,float* arr2,int N1,int N2)
{
  int Nx,Ny;
  int n_blocks,n_threads;
  int dev=0; // 1
  float time;
  size_t size;
  clock_t start,end;
  cudaSetDevice(dev);
  cudaDeviceProp deviceProp;
  start = clock();
  cudaGetDeviceProperties(&deviceProp, dev);
  Nx=N1;
  Ny=N2;
  n_threads=256;
  n_blocks=(Nx*Ny+n_threads-1)/n_threads;
  size=Nx*Ny*sizeof(float);
  cudaMalloc((void**)&d_A,size);
  cudaMalloc((void**)&d_B,size);
  cudaMemcpy(d_A, arr1, size, cudaMemcpyHostToDevice);
  cudaMemcpy(d_B, arr2, size, cudaMemcpyHostToDevice);
  vector_add<<<n_blocks,n_threads>>>(d_A,d_B,size);
  cudaMemcpy(arr1, d_A, size, cudaMemcpyDeviceToHost);
  printf("Running device %s \n",deviceProp.name);
  end = clock();
  time=float(end-start)/float(CLOCKS_PER_SEC);
  printf("time = %e\n",time);
}

int main()
{
int const nx = 20000,ny = nx;
static float a[nx*ny],b[nx*ny];
for(int i=0;i<nx;i++)
  {
  for(int j=0;j<ny;j++)
  {
    a[j+ny*i]=j+10*i;
    b[j+ny*i]=-(j+10*i);
  }
}
get_matrix(a,b,nx,ny);
return 0;
}

出力は次のとおりです。

Running device Quadro 400
time = 1.100000e-01

Running device Tesla C2075
time = 1.050000e+00

そして私の質問は次のとおりです。

  • 使用する GPU に応じてコードを変更する必要がありますか?
  • コードで指定されたブロック数、ブロックあたりのスレッド数と、GPU で使用可能なマルチプロセッサ数、マルチプロセッサあたりのコア数の間に関係はありますか?

Linux Open Suse 11.2 を実行しています。ソース コードは、nvcc コンパイラ (バージョン 4.2) を使用してコンパイルされます。

ご協力いただきありがとうございます!

4

1 に答える 1

1

2 回呼び出しget_matrix(a,b,nx,ny)て、2 番目のタイミング結果を取得してみてください。初めて CUDA API を呼び出すと、cuda コンテキストが作成されます。多くの場合、長い時間がかかります。

ブロック サイズとグリッド サイズを決定する方法については、CUDA C ベスト プラクティス ガイドのこのセクションを参照してください。

于 2013-01-09T14:17:08.977 に答える