使用 CUDA 内核导致堆栈溢出
我正在编程的代码有一个很大的问题。
我不是专家,来之前问过很多人。也纠正了很多事情。所以,我想我已经准备好向您展示代码并问您我的问题了。
我将把整个代码放在这里,以便让您更好地理解我的问题是什么。
我想要做的事情是,如果 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,isub_matrix,((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),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,y,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, 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,*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,isub_matrix,((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),cudaMemcpyHostToDevice);
//call the cuda kernel
twiddle_factor<<<1,256>>>(d_isub_matrix,d_osub_matrix);//<----
cudaMemcpy(osub_matrix,d_osub_matrix,((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),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,0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time,start,stop);
//Free memory in GPU
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在这段代码中看到了很多问题。
在将数据从 big_matrix 复制到 isub_matrix 之前,您没有为 isub_matrix 分配内存
您没有为 isub_matrix 从主机到设备执行任何 cudaMemcpy。在设备上为 isub_matrix 分配内存后,您需要复制数据。
我看到在 while 循环内您正在计算相同的数据。
for 循环应该依赖于 array_plus。
我建议你这样做
基于更新的版本:
我看到的错误是
并打电话。
然后
顺便说一句,事实并非如此
twiddle_factor<<<1,256>>(isub_matrix,osub_matrix);
应该是
twiddle_factor<<<1,256>>(d_isub_matrix,osub_matrix);
最终和完成的代码:
I see loads of problem in this code.
You are not allocating memory for isub_matrix before copying the data from big_matrix to isub_matrix
You are not doing any cudaMemcpy from host to device for isub_matrix. After allocating memory on the device for isub_matrix, you need to copy the data.
I see that inside the while loop you are computing the same data.
The for loop should be dependent on the array_plus.
I would suggest u to do this
Based on the updated version:
The error I see is
and call.
Then do
By the way, it is not
twiddle_factor<<<1,256>>>(isub_matrix,osub_matrix);
It should be
twiddle_factor<<<1,256>>>(d_isub_matrix,osub_matrix);
Final and completed code:
我认为问题就出在这条线上。
这是因为您在设备中同时分配了
osub_matrix
和isub_matrix
。I think the problem is in the line.
This is because you allocate both
osub_matrix
andisub_matrix
in the device.