Exception 程序启动时堆栈溢出异常(CUDA Monte Carlo Pi)

Exception 程序启动时堆栈溢出异常(CUDA Monte Carlo Pi),exception,cuda,stack-overflow,montecarlo,pi,Exception,Cuda,Stack Overflow,Montecarlo,Pi,我的问题是,当程序第一次进入main时,我在程序启动时收到堆栈溢出异常。我的程序是一个使用CUDA的并行蒙特卡罗Pi计算器。当我尝试在VisualStudio中调试程序时,异常会在我可以选择的任何断点之前弹出。感谢您的帮助 #include <stdio.h> #include <stdlib.h> #include <cuda.h> #include <curand.h> #include <curand_kernel.h> #de

我的问题是,当程序第一次进入main时,我在程序启动时收到堆栈溢出异常。我的程序是一个使用CUDA的并行蒙特卡罗Pi计算器。当我尝试在VisualStudio中调试程序时,异常会在我可以选择的任何断点之前弹出。感谢您的帮助

#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <curand.h>
#include <curand_kernel.h>

#define NUM_THREAD 512
#define NUM_BLOCK 65534

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Function to sum an array
__global__ void reduce0(float *g_odata) {
extern __shared__ int sdata[];

// each thread loads one element from global to shared mem
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
sdata[tid] = g_odata[i];
__syncthreads();

// do reduction in shared mem
for (unsigned int s=1; s < blockDim.x; s *= 2) { // step = s x 2
    if (tid % (2*s) == 0) { // only threadIDs divisible by the step participate
        sdata[tid] += sdata[tid + s];
    }
    __syncthreads();
}

// write result for this block to global mem
if (tid == 0) g_odata[blockIdx.x] = sdata[0];
}

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
__global__ void monteCarlo(float *g_odata, int  trials, curandState *states){
    extern __shared__ int sdata[];
//  unsigned int tid = threadIdx.x;
    unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int k, incircle;
    float x, y, z;
    incircle = 0;

    curand_init(1234, i, 0, &states[i]);

    for(k = 0; k < trials; k++){

    x = curand_uniform(&states[i]);
    y = curand_uniform(&states[i]);
    z = sqrt(x*x + y*y);
    if (z <= 1) incircle++;
    else{}
    }
    __syncthreads();
    g_odata[i] = incircle;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int main() {

    float* solution = (float*)calloc(100, sizeof(float));
    float *sumDev, sumHost[NUM_BLOCK*NUM_THREAD];
    int trials, total; 
    curandState *devStates;



    trials = 100;
    total = trials*NUM_THREAD*NUM_BLOCK;

    dim3 dimGrid(NUM_BLOCK,1,1); // Grid dimensions
    dim3 dimBlock(NUM_THREAD,1,1); // Block dimensions
    size_t size = NUM_BLOCK*NUM_THREAD*sizeof(float); //Array memory size
    cudaMalloc((void **) &sumDev, size); // Allocate array on device
    cudaMalloc((void **) &devStates, size*sizeof(curandState));
    // Do calculation on device by calling CUDA kernel
    monteCarlo <<<dimGrid, dimBlock, size>>> (sumDev, trials, devStates);
        // call reduction function to sum
    reduce0 <<<dimGrid, dimBlock, size>>> (sumDev);
    // Retrieve result from device and store it in host array
    cudaMemcpy(sumHost, sumDev, size, cudaMemcpyDeviceToHost);

    *solution = 4*(sumHost[0]/total);
    printf("%.*f\n", 1000, *solution);
    free (solution);
    //*solution = NULL;
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义NUM_线程512
#定义数字块65534
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//函数对数组求和
__全局无效缩减0(浮点*g_odata){
外部共享数据数据[];
//每个线程将一个元素从全局加载到共享mem
unsigned int tid=threadIdx.x;
无符号整数i=blockIdx.x*blockDim.x+threadIdx.x;
sdata[tid]=g_odata[i];
__同步线程();
//是否减少共享内存
对于(无符号整数s=1;s如果(z您正在声明共享内存的大小=大小;如下所示

monteCarlo <<<dimGrid, dimBlock, size>>>
对于这类内核,我个人更喜欢方法二,因为共享内存与线程数量成正比,但线程数量是恒定的,而且速度稍快

编辑

除了上述问题外,我怀疑这是否也会造成问题

 cudaMalloc((void **) &devStates, size*sizeof(curandState));
因为尺寸本身就是这样

size = NUM_BLOCKS * NUM_THREADS * sizeof(float);
也许你想这样做

cudaMalloc((void **) &devStates, (NUM_BLOCKS *NUM_THREADS)*sizeof(curandState));

至于实际的堆栈溢出问题,您可能想看看。

我假设问题是这样的:

float *sumDev, sumHost[NUM_BLOCK*NUM_THREAD];
为了


这就给您留下了大约130Mb的静态声明数组。我怀疑编译器运行库是否能够处理如此大的静态分配,这就是为什么会出现即时堆栈溢出。用动态分配替换它,堆栈溢出问题就会消失。但请仔细阅读,因为一旦修复堆栈溢出,则e CUDA代码本身也需要一些重新设计才能工作。

我怀疑这是初始堆栈溢出的原因。你是对的。对幕后情况不太熟悉。我只是针对我发现的明显问题指出了解决方案。感谢你在帖子中澄清的内容。啊,是的,这导致了问题。帕万的帖子也帮助了我重新设计我的CUDA代码。谢谢
size = NUM_BLOCKS * NUM_THREADS * sizeof(float);
cudaMalloc((void **) &devStates, (NUM_BLOCKS *NUM_THREADS)*sizeof(curandState));
float *sumDev, sumHost[NUM_BLOCK*NUM_THREAD];
#define NUM_THREAD 512
#define NUM_BLOCK 65534