我不是专家,在来这里之前我问了很多人.也纠正了很多事情.所以,我想我已准备好向您展示代码并向您提问我的问题.
我会把整个代码放在这里,以便让你很好地理解我的问题.
我想做的事情是,如果ARRAY_SIZE对于THREAD_SIZE来说太大了,那么我将大数组的数据放入一个较小的数组中,特别是用THREAD_SIZE大小创建.
然后,我将它发送到内核并做我必须做的任何事情.但是我有问题
isub_matrix[x*THREAD_SIZE+y]=big_matrix[x*ARRAY_SIZE+y];
由于堆栈溢出,代码停止的位置.首先,我制作了big_matrix的双指针.但freenode irc网络#cuda频道的人告诉我,cpu内存太大而无法处理它,我应该创建一个线性指针.我做到了,但我仍然有同样的堆栈溢出问题.所以,在这里…经过一些更改后更新,但还没有工作(堆栈溢出停止,但是链接和清单更新失败)
#define ARRAY_SIZE 2048 #define THREAD_SIZE 32 #define PI 3.14 int main(int argc,char** argv) { int array_plus=0,x,y; float time; //unsigned int memsize=sizeof(float)*THREAD_SIZE*THREAD_SIZE; //bool array_rest; cudaEvent_t start,stop; float *d_isub_matrix; float *big_matrix = new float[ARRAY_SIZE*ARRAY_SIZE]; float *big_matrix2 = new float[ARRAY_SIZE*ARRAY_SIZE]; float *isub_matrix = new float[THREAD_SIZE*THREAD_SIZE]; float *osub_matrix = new float[THREAD_SIZE*THREAD_SIZE]; //if the array's size is not compatible with the thread's size,it won't work. //array_rest=(ARRAY_SIZE*ARRAY_SIZE)/(THREAD_SIZE*THREAD_SIZE); //isub_matrix=(float*) malloc(memsize); //osub_matrix=(float*) malloc(memsize); if(((ARRAY_SIZE*ARRAY_SIZE)%(THREAD_SIZE*THREAD_SIZE)==0)) { //allocating space in cpu memory and GPU memory for the big matrix and its sub matrixes //it has to be like this (lots of loops) //populating the big array for(x=0;x<ARRAY_SIZE;x++) { for(y=0;y<ARRAY_SIZE;y++) big_matrix[x*ARRAY_SIZE+y]=rand()%10000; } //kind of loop for the big array //Start counting the time of processing (everything) cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start,0); while(array_plus<ARRAY_SIZE) { //putting the big array's values into the sub-matrix for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[(x+array_plus)*ARRAY_SIZE+y]; } cudaMalloc((void**)&d_isub_matrix,THREAD_SIZE*THREAD_SIZE*sizeof(float)); cudaMalloc((void**)&osub_matrix,THREAD_SIZE*THREAD_SIZE*sizeof(float)); cudaMemcpy(d_isub_matrix,isub_matrix,((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),cudaMemcpyHostToDevice); //call the cuda kernel twiddle_factor<<<1,256>>>(isub_matrix,osub_matrix);//<---- cudaMemcpy(osub_matrix,cudaMemcpyDeviceToHost); array_plus=array_plus+THREAD_SIZE; for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) big_matrix2[x*THREAD_SIZE+array_plus+y]=osub_matrix[x*THREAD_SIZE+y]; } array_rest=array_plus+(ARRAY_SIZE); cudaFree(isub_matrix); cudaFree(osub_matrix); system("PAUSE"); } //Stop the time cudaEventRecord(stop,0); cudaEventSynchronize(stop); cudaEventElapsedTime(&time,start,stop); //Free memory in GPU printf("The processing time took... %fms to finish",time); system("PAUSE"); } printf("The processing time took...NAO ENTROU!"); system("PAUSE"); return 0; } //things to do: TRANSPOSITION!!!!
另一个问题是关于平行部分.
编译器(Visual Studio)说我一次搞了太多pow()和exp().
我该如何解决这个问题?
if((xIndex<THREAD_SIZE)&&(yIndex<THREAD_SIZE)) { block[xIndex][yIndex]=exp(sum_sin[xIndex][yIndex])+exp(sum_cos[xIndex][yIndex]); }
原始代码在这里.我评论它是因为我想知道至少我的代码是否在GPU中占据了一些价值.但它甚至没有启动内核……太可悲了)
__global__ void twiddle_factor(float *isub_matrix,float *osub_matrix) { __shared__ float block[THREAD_SIZE][THREAD_SIZE]; // int x,y,z; unsigned int xIndex = threadIdx.x; unsigned int yIndex = threadIdx.y; /* int sum_sines=0.0; int sum_cosines=0.0; float sum_sin[THREAD_SIZE],sum_cos[THREAD_SIZE]; float angle=(2*PI)/THREAD_SIZE; //put into shared memory the FFT calculation (F(u)) for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) { for(z=0;z<THREAD_SIZE;z++) { sum_sines=sum_sin+sin(isub_matrix[y*THREAD_SIZE+z]*(angle*z)); sum_cosines=sum_cos+cos(isub_matrix[y*THREAD_SIZE+z]*(angle*z)); } sum_sin[x][y]=sum_sines/THREAD_SIZE; sum_cos[x][y]=sum_cosines/THREAD_SIZE; } } */ if((xIndex<THREAD_SIZE)&&(yIndex<THREAD_SIZE)) block[xIndex][yIndex]=pow(THREAD_SIZE,0.5); //block[xIndex][yIndex]=pow(exp(sum_sin[xIndex*THREAD_SIZE+yIndex])+exp(sum_cos[xIndex*THREAD_SIZE+yIndex]),0.5); __syncthreads(); //transposition X x Y //transfer back the results into another sub-matrix that is allocated in cpu if((xIndex<THREAD_SIZE)&&(yIndex<THREAD_SIZE)) osub_matrix[yIndex*THREAD_SIZE+xIndex]=block[xIndex][yIndex]; __syncthreads(); }
感谢您阅读所有内容!
以下是整个代码:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #define ARRAY_SIZE 2048 #define THREAD_SIZE 32 #define PI 3.14 __global__ void twiddle_factor(float *isub_matrix,float *osub_matrix) { __shared__ float block[THREAD_SIZE][THREAD_SIZE]; int x,z; unsigned int xIndex = threadIdx.x; unsigned int yIndex = threadIdx.y; float sum_sines=0.0; //float expo_sums; float sum_cosines=0.0; float sum_sin[THREAD_SIZE][THREAD_SIZE],sum_cos[THREAD_SIZE][THREAD_SIZE]; float angle=(2*PI)/THREAD_SIZE; //put into shared memory the FFT calculation (F(u)) for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) { for(z=0;z<THREAD_SIZE;z++) { sum_sines=sum_sines+sin(isub_matrix[y*THREAD_SIZE+z]*(angle*z)); sum_cosines=sum_cosines+cos(isub_matrix[y*THREAD_SIZE+z]*(angle*z)); } sum_sin[x][y]=sum_sines/THREAD_SIZE; sum_cos[x][y]=sum_cosines/THREAD_SIZE; } } if((xIndex<THREAD_SIZE)&&(yIndex<THREAD_SIZE)) { block[xIndex][yIndex]=exp(sum_sin[xIndex][yIndex])+exp(sum_cos[xIndex][yIndex]); } __syncthreads(); //transposition X x Y //transfer back the results into another sub-matrix that is allocated in cpu if((xIndex<THREAD_SIZE)&&(yIndex<THREAD_SIZE)) osub_matrix[yIndex*THREAD_SIZE+xIndex]=block[xIndex][yIndex]; __syncthreads(); } int main(int argc,stop; float *d_isub_matrix,*d_osub_matrix; float *big_matrix = new float[ARRAY_SIZE*ARRAY_SIZE]; float *big_matrix2 = new float[ARRAY_SIZE*ARRAY_SIZE]; float *isub_matrix = new float[THREAD_SIZE*THREAD_SIZE]; float *osub_matrix = new float[THREAD_SIZE*THREAD_SIZE]; //if the array's size is not compatible with the thread's size,it won't work. //array_rest=(ARRAY_SIZE*ARRAY_SIZE)/(THREAD_SIZE*THREAD_SIZE); //isub_matrix=(float*) malloc(memsize); //osub_matrix=(float*) malloc(memsize); if(((ARRAY_SIZE*ARRAY_SIZE)%(THREAD_SIZE*THREAD_SIZE)==0)&&(ARRAY_SIZE>=THREAD_SIZE)) { //allocating space in cpu memory and GPU memory for the big matrix and its sub matrixes //it has to be like this (lots of loops) //populating the big array for(x=0;x<ARRAY_SIZE;x++) { for(y=0;y<ARRAY_SIZE;y++) big_matrix[x*ARRAY_SIZE+y]=rand()%10000; } //kind of loop for the big array //Start counting the time of processing (everything) cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start,0); while(array_plus<ARRAY_SIZE) { //putting the big array's values into the sub-matrix for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[x*ARRAY_SIZE+y]; } cudaMalloc((void**)&d_isub_matrix,THREAD_SIZE*THREAD_SIZE*sizeof(float)); cudaMalloc((void**)&d_osub_matrix,THREAD_SIZE*THREAD_SIZE*sizeof(float)); cudaMemcpy(d_isub_matrix,256>>>(d_isub_matrix,d_osub_matrix);//<---- cudaMemcpy(osub_matrix,d_osub_matrix,cudaMemcpyDeviceToHost); array_plus=array_plus+THREAD_SIZE; for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) big_matrix2[x*THREAD_SIZE+array_plus+y]=osub_matrix[x*THREAD_SIZE+y]; } cudaFree(isub_matrix); cudaFree(osub_matrix); cudaFree(d_osub_matrix); cudaFree(d_isub_matrix); } //Stop the time cudaEventRecord(stop,stop); //Free memory in GPU
解决方法
>在将数据从big_matrix复制到isub_matrix之前,您没有为isub_matrix分配内存
for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[x*ARRAY_SIZE+y]; }
>您没有为isub_matrix从主机到设备执行任何cudaMemcpy.在设备上为isub_matrix分配内存后,您需要复制数据.
>我在while循环中看到你正在计算相同的数据.
//putting the big array's values into the sub-matrix for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[x*ARRAY_SIZE+y]; }
for循环应该依赖于array_plus.
我建议你这样做
for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[(x+array_plus)*ARRAY_SIZE+y]; }
>而且,我不觉得使用array_rest.那用的是什么?
基于更新版本:
我看到的错误是
>您正在使用osub_matrix作为主机和设备指针.我建议你创建另一个浮点指针并将其用于设备
float *d_osub_matrix;
cudaMalloc((void**)&d_osub_matrix,THREAD_SIZE*THREAD_SIZE*sizeof(float));
并打电话.
twiddle_factor<<<1,d_osub_matrix);
然后做
cudaMemcpy(osub_matrix,cudaMemcpyDeviceToHost);
>顺便说一下,事实并非如此
twiddle_factor<<< 1256>>>(isub_matrix,osub_matrix);
它应该是
twiddle_factor<<< 1256>>>(d_isub_matrix,osub_matrix);
最终和完成的代码:
int main(int argc,char** argv) { int array_plus=0,y; int array_plus_x,array_plus_y; float time; //unsigned int memsize=sizeof(float)*THREAD_SIZE*THREAD_SIZE; //bool array_rest; cudaEvent_t start,0); for(array_plus_x = 0; array_plus_x < ARRAY_SIZE; array_plus_x += THREAD_SIZE) for(array_plus_y = 0; array_plus_y < ARRAY_SIZE; array_plus_y += THREAD_SIZE) { //putting the big array's values into the sub-matrix for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) isub_matrix[x*THREAD_SIZE+y]=big_matrix[(x+array_plus_x)*ARRAY_SIZE+(y+array_plus_y)]; } cudaMalloc((void**)&d_isub_matrix,cudaMemcpyHostToDevice); //call the cuda kernel dim3 block(32,32); twiddle_factor<<<1,block>>>(d_isub_matrix,cudaMemcpyDeviceToHost); for(x=0;x<THREAD_SIZE;x++) { for(y=0;y<THREAD_SIZE;y++) big_matrix2[(x+array_plus_x)*ARRAY_SIZE+(y+array_plus_y)]=osub_matrix[x*THREAD_SIZE+y]; } cudaFree(d_osub_matrix); cudaFree(d_isub_matrix); } //Stop the time cudaEventRecord(stop,stop); //Free memory in GPU