2012-09-10 20 views
4

我正在CUDA中編寫我的第一個程序。它是一個素數生成器。它的工作原理,但它只比同等的單線程C++代碼快50%。 CPU版本使用100%的一個內核。 GPU版本只使用20%的GPU。該CPU是一個i5(2310)。 GPU是GF104。CUDA素數生成器的低性能

如何提高此算法的性能?

我的完整程序如下。

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); 
} 

我試圖用一個二維數組和for循環內核,但未能得到正確的結果。

回答

3

歡迎來到Stack Overflow。

這裏有一些潛在的問題:

  • N = 1000是太低了。既然你有1024 threadsPerBlock,你的內核將只運行一個塊,這不足以利用GPU。嘗試N = 1000000,以便您的內核啓動將近1000個塊。

  • 你在GPU上做的工作很少(每個測試編號有4個模數運算)。因此,在CPU上執行這些操作可能比從GPU複製它們(通過PCIe總線)要快。

爲了使用GPU來查找素數值得值得,我認爲您需要在GPU上實現整個算法,而不僅僅是模數運算。