私はプログラミングしているコードに大きな問題があります。
私は専門家ではなく、ここに来る前に多くの人に尋ねました。多くのことも訂正しました。だから、私はあなたにコードを示し、あなたに私の質問をする準備ができていると思う。
私はあなたの問題が何であるかをよく理解できるように、コード全体をここに入れます。 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<<<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
#include
#include
#include
#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<<<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
私はこのコードで問題の負荷を参照してください。
-
You are not allocating memory for isub_matrix before copying the
data from big_matrix to isub_matrixfor(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]; }
-
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.//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,256>>>(d_isub_matrix,d_osub_matrix);
それから
cudaMemcpy(osub_matrix,d_osub_matrix, ((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),cudaMemcpyDeviceToHost);
-
By the way, it is not
twiddle_factor<<<1,256>>>(isub_matrix,osub_matrix);
そのはず
twiddle_factor<<<1,256>>>(d_isub_matrix,osub_matrix);
最終的なコードと完了したコード:
int main(int argc, char** argv)
{
int array_plus=0,x,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,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; 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,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
dim3 block(32,32);
twiddle_factor<<<1,block>>>(d_isub_matrix,d_osub_matrix);//<----
cudaMemcpy(osub_matrix,d_osub_matrix,((THREAD_SIZE*THREAD_SIZE)*sizeof(float)),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,0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time,start,stop);
//Free memory in GPU