4

私はCUDAで最初のプログラムを書いています。素数ジェネレーターです。動作しますが、同等のシングル スレッド C++ コードよりも 50% 高速です。CPU 版は 1 コアを 100% 使用します。GPU バージョンは、GPU の 20% のみを使用します。CPUはi5(2310)です。GPUはGF104です。

このアルゴリズムのパフォーマンスを改善するにはどうすればよいですか?

私の完全なプログラムは次のとおりです。

int* d_C;

using namespace std;

__global__ void primo(int* C, int N, int multi)
{
  int i = blockIdx.x*blockDim.x + threadIdx.x;
  if (i < N) 
  {
    if(i%2==0||i%3==0||i%5==0||i%7==0)
    {
      C[i]=0;           
    }
    else
    {
      C[i]=i+N*multi;
    }
  }
}

int main()
{
  cout<<"Prime numbers \n";
  int N=1000;
  int h_C[1000];
  size_t size=N* sizeof(int);
  cudaMalloc((void**)&d_C, size);

  int threadsPerBlock = 1024;
  int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
  vector<int> lista(100000000);
  int c_z=0;

  for(int i=0;i<100000;i++)
  {
    primo<<<blocksPerGrid, threadsPerBlock>>>(d_C, N,i);    
    cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);         
    for(int c=0;c<N;c++)
    {   
      if(h_C[c]!=0)
      {
        lista[c+N*i-c_z]=h_C[c];
      }
      else
      {
        c_z++;
      }
    }   
  }
  lista.resize(lista.size()-c_z+1);
  return(0);
}

カーネルで2D 配列とforループを使用してみましたが、正しい結果を得ることができませんでした。

4

1 に答える 1

3

スタック オーバーフローへようこそ。

いくつかの潜在的な問題を次に示します。

  • N = 1000 は低すぎます。1024 がthreadsPerBlockあるため、カーネルは 1 つのブロックのみを実行しますが、これは GPU を利用するには不十分です。カーネルの起動がほぼ 1000 ブロックになるように、N = 1000000 を試してください。

  • GPU でほとんど作業を行っていません (テストされた数値ごとに 4 つのモジュラス演算)。そのため、これらの操作を GPU から (PCIe バス経由で) コピーするよりも、CPU で実行する方がおそらく高速です。

素数を見つけるために GPU を使用する価値があるようにするには、モジュラス演算だけでなく、アルゴリズム全体を GPU に実装する必要があると思います。

于 2012-09-11T03:12:52.727 に答える