我想並行化CUDA C中的函數,該函數將計算所有向量的總和等於向量元素和不大於k的元素。例如,如果向量元素的數量n是5,sum = 10和k = 3,那麼滿足這個條件的向量的數量是101.我已經在CUDA C中做了這個函數,但問題是當塊和線程都大於1.我知道問題出在for
週期,我應該改變它,但我不知道從哪裏開始。當我使用塊和線程調用函數的功能等於1時,函數以傳統方式工作,一切都很好,但在這種情況下,函數不是並行化的。並行化函數將計算所有向量的總和等於向量元素和不大於k的元素
程序的源代碼是:
//function that count number of vectors
__device__ void count(int *vector, int *total, int n, int s)
{
int i,sum=0;
for(i=blockIdx.x*blockDim.x+threadIdx.x;i<n;i+=blockDim.x*gridDim.x)
{
sum+=vector[i];
__syncthreads();
}
if(sum==s)
{
total[0]=total[0]+1;
}
}
//main function
__global__ void computeVectors(int *vector, int n, int kk, int s, int *total)
{
int k=0;
int j,i,next;
while(1)
{
//this is the problem, in for cycle
for(j=blockIdx.x*blockDim.x+threadIdx.x; j<=kk; j+=blockDim.x*gridDim.x)
{
vector[k]=j;
count(vector, total, n, s);
__syncthreads();
}
for(i=blockIdx.x*blockDim.x+threadIdx.x; i<n; i+=blockDim.x*gridDim.x)
{
if(vector[i]<kk)
break;
}
next=i;
vector[next]++;
for(i=blockIdx.x*blockDim.x+threadIdx.x; i<sledno; i+=blockDim.x*gridDim.x)
{
vector[i]=0;
__syncthreads();
}
k=0;
if(next>=n)
break;
}
}
int main()
{
cudaError_t err = cudaSuccess;
int n,k,sum;
int counter=0;
printf("Enter the length of vector n=");
scanf("%d",&n);
printf("Enter the max value of vector elements k=");
scanf("%d",&k);
printf("Enter the sum of vector elements sum=");
scanf("%d",&sum);
//initial vector with length n
int *vec_h, *vec_d;
size_t sizevec=n*sizeof(int);
vec_h=(int *)malloc(sizevec);
cudaMalloc((void **) &vec_d, sizevec);
for(counter=0; counter<n; counter++)
{
vec_h[counter]=0;
}
cudaMemcpy(vec_d, vec_h, sizevec, cudaMemcpyHostToDevice);
int *total_h, *total_d;
size_t size=1*sizeof(int);
total_h=(int *)malloc(size);
cudaMalloc((void **) &total_d, size);
total_h[0]=0;
cudaMemcpy(total_d, total_h, size, cudaMemcpyHostToDevice);
//calling the main function
computeVectors<<<1, 1>>>(vec_d, n, k, sum, total_d);
cudaThreadSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess)
{
fprintf(stderr, "Error: %s!\n", cudaGetErrorString(err));
exit(EXIT_FAILURE);
}
cudaMemcpy(total_h, total_d, size, cudaMemcpyDeviceToHost);
printf("Number of vectors that satisfy condition is %d\n", total_h[0]);
free(vec_h);
cudaFree(vec_d);
free(total_h);
cudaFree(total_d);
return 0;
}
我假設矢量元素的範圍可以從0到'k','k'預計爲一個正數?既然你用1個線程的1個線程塊調用內核,你根本沒有真正的並行化任何東西。你只是在運行序列碼。你有沒有嘗試過並行?你甚至有戰略嗎?例如,如果您有多個線程,每個線程會做什麼? (也許是一個單獨的模式測試?)每個塊可能負責什麼? (也許是測試的整體空間的一部分?) –
是的,k是正數,我知道當塊和線程的數量是1時,代碼正在運行串行。如何使用線程進行模式測試? – Dragon
要測試的空間是所有長度爲「n」的向量,其中每個向量元素具有「k」+ 1個可能的值。因此,使用樸素的蠻力方法,有(k + 1)^ n個可能的向量來測試。一種方法是讓每個線程都執行全部工作(矢量生成,和計算,和測試)來測試單個矢量,然後讓整個網格遍歷(k + 1)^ n個矢量的整個空間。對於正確測試的向量,可以在每個線程的末尾使用原子操作來更新'count'值。這將適用於符合'unsigned long'的(k + 1)^ n。 –