2013-10-13 35 views
0

首先,我是CUDA的新手,我正在努力學習,所以也許我做錯了什麼。我想比較CUDA性能與Intel內部函數實現的等效功能,希望CUDA能夠產生更好的結果。CUDA vs Intel AVX/SSE矢量求和性能問題

但令我驚訝的是,那不是我所看到的。我的功能非常簡單,我只需添加兩個矢量並將結果存儲在第三個矢量中。我的CUDA代碼是基本的,因爲它得到,在設置功能我:

void cudaAddVectors(float* vectorA, float* vectorB, float* sum, int numElements) 
{ 
// 
// Allocate the memory on the device 
// 
float* dvA; 
float* dvB; 
float* dvC; 

cudaMalloc((void**)&dvA, numElements * sizeof(float)); 
cudaMalloc((void**)&dvB, numElements * sizeof(float)); 
cudaMalloc((void**)&dvC, numElements * sizeof(float)); 

// 
// Copy the host vectors to device vectors 
// 
cudaMemcpy(dvA, vectorA, numElements * sizeof(float), cudaMemcpyHostToDevice); 
cudaMemcpy(dvB, vectorB, numElements * sizeof(float), cudaMemcpyHostToDevice); 

// 
// Perform the sum on the device and time it 
// 
deviceSumLink(dvA, dvB, dvC, numElements); 

// 
// Now get the results back to the host 
// 
cudaMemcpy(sum, dvC, numElements * sizeof(float), cudaMemcpyDeviceToHost); 

// Cleanup and go home 
cudaFree(dvA); 
cudaFree(dvB); 
cudaFree(dvC); 

}

則設備代碼是用塊或線程運行,就像這樣:

void deviceSumLink(float* a, float* b, float* c, int numElements) 
{ 
    //deviceSum<<<numElements, 1>>>(a,b,c); 
    deviceSumThreads<<<1, numElements>>>(a,b,c); 
} 

和設備上運行的實際代碼:

__global__ void deviceSum(float* a, float* b, float* c) 
{ 
    int index = blockIdx.x; 
    c[index] = a[index] + b[index]; 
} 

__global__ void deviceSumThreads(float* a, float* b, float* c) 
{ 
    int index = threadIdx.x; 
    c[index] = a[index] + b[index]; 
} 

我計時英特爾版本和CUDA總結不同大小的向量並驗證兩者都產生了準確的結果。對於CUDA調用,我只爲deviceSumLink調用計時,而不是內存設置和所有內容,但無論調用內核的方法如何,英特爾內核版本(使用8單元陣列)都只是抽出CUDA水。基本上,功能的英特爾SIMD版本是快10倍的東西!

我沒有想到這一點,所以我把這歸因於我是一個CUDA中的完全新手。那麼我做錯了什麼?我認爲CUDA應該在這些事情上快得多,我認爲我不應該正確地使用它或什麼。

如果您有一些見解,我會很感激評論!

Thx!

+0

忘了補充我跑這對MacBook Pro的視網膜與2.3 GHz的英特爾酷睿i7以及NVIDIA GeForce GT 650M – Vulk

+2

你是說你的標杆正在與* 8輛花車陣做*? (即numElements = 8)? – talonmies

+0

numElements可以是8的任何倍數,向量是浮動的,是的。英特爾希望內存對齊到32字節的邊界,以便它們對齊。 – Vulk

回答

1

每塊只使用1個塊或1個線程添加矢量將不會完全利用GPU。由於the limitation of thread size per block and block size,它們不適用於大載體。

要正確添加兩個大載體,並獲得最大的性能,你需要這樣的

__global__ void 
vectorAdd(const float *A, const float *B, float *C, int numElements) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 

    if (i < numElements) 
    { 
     C[i] = A[i] + B[i]; 
    } 
} 

內核並使用以下線程調用它/塊設置

int threadsPerBlock = 256; 
int blocksPerGrid =(numElements + threadsPerBlock - 1)/threadsPerBlock; 

vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements); 

請參閱本CUDA示例瞭解更多詳情。

http://docs.nvidia.com/cuda/cuda-samples/#vector-addition

+0

啊!這可能是我做錯了。謝謝埃裏克,我會給它一個旋轉... – Vulk