Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 堆栈空间不足错误(堆栈溢出错误)_C++_Cuda - Fatal编程技术网

C++ 堆栈空间不足错误(堆栈溢出错误)

C++ 堆栈空间不足错误(堆栈溢出错误),c++,cuda,C++,Cuda,我试图计算一个大小为N(平方矩阵)的矩阵乘法,但我得到了一个堆栈溢出错误(我是Cuda新手): 如果我在N300时测试代码,则代码不起作用,显示堆栈溢出错误,但图形卡GF 820M中有足够的内存。 如果N=300,则300*300*4(浮点大小)=360000字节:设备中为浮点类型数组分配的必要空间。这里必须为3个表分配乘法。因此,360000*3=1080000字节,如果我控制CudaMalloc,则不显示任何内容 我告诉你,我的主要目标是测试足够大的N。我如何解决这个问题?提前感谢您可能提供

我试图计算一个大小为N(平方矩阵)的矩阵乘法,但我得到了一个堆栈溢出错误(我是Cuda新手):

如果我在N<300时测试代码,一切正常,但如果在N>300时测试代码,则代码不起作用,显示堆栈溢出错误,但图形卡GF 820M中有足够的内存。 如果N=300,则300*300*4(浮点大小)=360000字节:设备中为浮点类型数组分配的必要空间。这里必须为3个表分配乘法。因此,360000*3=1080000字节,如果我控制CudaMalloc,则不显示任何内容

我告诉你,我的主要目标是测试足够大的N。我如何解决这个问题?提前感谢您可能提供的任何帮助

#include <stdio.h>
#include<device_launch_parameters.h>
#include<cuda.h>
#include<time.h>
#include<cuda_runtime.h>
#include <math.h>

__global__ void MatrixMul( float *Md , float *Nd , float *Pd , const int WIDTH )
{   // calculate thread id
          unsigned  int row = blockIdx.y*blockDim.y+threadIdx.y;
          unsigned  int col = blockIdx.x*blockDim.x+threadIdx.x;
for (int k = 0 ; k<WIDTH ; k++ )
         { Pd[row*WIDTH + col]+= Md[row * WIDTH + k ] * Nd[ k * WIDTH + col] ;  }}


int main ()
{       const int i=64 ;
       cudaEvent_t start, stop;
        float time;
       cudaEventCreate(&start);
       cudaEventCreate(&stop);
       const int WIDTH =300;
       cudaError_t cudaStatus;

   float array1_h[WIDTH][WIDTH] ,array2_h[WIDTH][WIDTH] ,M_result_array_h[WIDTH][WIDTH];
   float *array1_d , *array2_d ,*M_result_array_d ; // device array



  // Allocate GPU buffers for 2 vectors (two input, one output) 

    cudaStatus = cudaMalloc((void **) &array1_d , WIDTH*WIDTH*sizeof (float));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!"); }  


    cudaStatus = cudaMalloc((void **) &array2_d , WIDTH*WIDTH*sizeof (float));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!"); }  




       for ( int i = 0 ; i<WIDTH ; i++ ) { 
           for (int j = 0 ; j<WIDTH ; j++ )
           { array1_h[i][j] = 1 ; array2_h[i][j] = 2 ; }}


  //copy host array to device array; cudaMemcpy ( dest , source , WIDTH , direction )



  cudaMemcpy ( array1_d , array1_h , WIDTH*WIDTH*sizeof (float) , cudaMemcpyHostToDevice ) ;

  cudaMemcpy ( array2_d , array2_h , WIDTH*WIDTH*sizeof (float) , cudaMemcpyHostToDevice ) ;



  //allocating memory for resultent device array

  cudaStatus = cudaMalloc((void **) &M_result_array_d , WIDTH*WIDTH*sizeof (float) ) ;
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!"); }  

  //calling kernal

  dim3 dimBlock( i,i, 1 ) ;
  dim3 dimGrid ( ((WIDTH-1)/i) +1 , ((WIDTH-1)/i)+1 ,1 ) ;

  cudaEventRecord(start, 0);
MatrixMul <<<dimGrid,dimBlock>>> ( array1_d , array2_d ,M_result_array_d , WIDTH) ;
    cudaEventRecord(stop, 0);
   cudaEventSynchronize(stop);
   cudaEventElapsedTime(&time, start, stop);
   printf ("taille du probleme:%d Time for the kernel: %f \n",WIDTH,time);


  //copy back result_array_d to result_array_h

  cudaMemcpy(M_result_array_h , M_result_array_d , WIDTH*WIDTH*sizeof(float) , cudaMemcpyDeviceToHost) ;


  //printf the result array
  for (int i = 0 ; i<WIDTH ; i++ )
  { for (int j = 0 ; j < WIDTH ; j++ )
     {   printf ("%f   ",M_result_array_h[i][j] ) ; }
              printf ("\n") ; } 


    cudaFree(array1_d);
    cudaFree(array2_d);
    cudaFree(M_result_array_h);


  system("pause") ; }
#包括
#包括
#包括
#包括
#包括
#包括
__全局无效矩阵MUL(浮点*Md、浮点*Nd、浮点*Pd、常量整数宽度)
{//计算线程id
unsigned int row=blockIdx.y*blockDim.y+threadIdx.y;
unsigned int col=blockIdx.x*blockDim.x+threadIdx.x;

对于(int k=0;k使用rtContextGetStackSize/rtContextSetStackSize找出堆栈的大小,并根据需要将其设置得更大。 请记住,图形卡上的内存与其他图形进程共享,不能全部使用

此外,您可以对矩阵进行分区,并使用逐块算法(而不是整个矩阵)计算a

  • 堆栈溢出问题与CUDA无关。这些分配:

    float array1_h[WIDTH][WIDTH] ,array2_h[WIDTH][WIDTH] ,M_result_array_h[WIDTH][WIDTH];
    
    由编译器在堆栈上创建。堆栈空间有限。(这是主机代码,因此这里的堆栈与GPU无关。)

    解决这一问题的一种可能方法是为这些变量创建动态分配,这将在堆上进行,堆没有与堆栈相同的限制

    因此,一个可能的解决方案是替换此:

    float array1_h[WIDTH][WIDTH] ,array2_h[WIDTH][WIDTH] ,M_result_array_h[WIDTH][WIDTH];
    
    为此:

    typedef float ar_type[WIDTH];
    ar_type *array1_h, *array2_h, *M_result_array_h;
    array1_h = (ar_type *)malloc(WIDTH*WIDTH*sizeof(float));
    array2_h = (ar_type *)malloc(WIDTH*WIDTH*sizeof(float));
    M_result_array_h = (ar_type *)malloc(WIDTH*WIDTH*sizeof(float));
    
  • 还请注意:

    const int i=64 ;
    ...
    dim3 dimBlock( i,i, 1 ) ;
    
    无效。您正在请求64x64线程块(总共4096个线程),这对于任何CUDA GPU都是不合法的。您可以通过将
    i
    更改为32来解决此特定问题

  • 修复后,您的内核似乎没有线程检查来防止越界线程执行和生成越界访问。您可以通过在内核for循环之前添加此线程检查来修复此问题:

    if ((row < WIDTH) && (col < WIDTH))
    
    我想你的意思是:

    cudaFree(M_result_array_d);
    

  • 如果您添加到代码中,和/或使用
    cuda memcheck

    运行代码,您可以发现这些其他错误(2-4)。对于这样一个简单的程序,您可以将矩阵定义为全局矩阵,这样它们就不会在堆栈上定义。非常感谢我更正代码一切都很顺利
    cudaFree(M_result_array_d);