-3

此代码应该使用几何布朗运动方法生成股票路径。对于每条路径,我都有10步骤,但是,正如您在下面看到的,从第三条路径开始,所有的东西都没有0,这不是我想要的。错误在哪里?

#include <iostream>
#include <iomanip>

#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <curand_kernel.h>

const int numSims(10);
const int threadBlockSize(4);

__global__ void generatePaths(float* path)
{
    float r=0.1;
    float sigma=0.3;
    float S0=100;
    float K=100;
    float t=1;

    int steps=10;
    float dt=t/float(steps);

    curandState s;
    int tid=blockIdx.x*blockDim.x+threadIdx.x;
    curand_init(tid, 0, 0, &s);

    float *value=path+tid;
    float S=S0;
    for(unsigned int i=0; i<steps; ++i)
    {
        S=S*expf((r-0.5*sigma*sigma)*dt+sigma*sqrt(dt)*curand_normal(&s));
        *(path+tid+i)=S;
    }
}

int main()
{
    dim3 grid;
    dim3 block;
    block.x=threadBlockSize;
    grid.x=(numSims+threadBlockSize-1)/threadBlockSize;

    int steps=10;
    float *da;
    cudaMalloc((void**)&da, numSims*steps*sizeof(float));
    generatePaths<<<grid, block>>>(da);

    float *values;
    values=(float*)malloc(numSims*steps*sizeof(float));
    cudaMemcpy(values, da, numSims*steps*sizeof(float), cudaMemcpyDeviceToHost);

    for(int i=0; i<numSims; i++)
    {
        for(int j=0; j<steps; j++)
        {
            std::cout<<values[i*steps+j]<<" ";
        }
        std::cout<<std::endl;
    }
    return 0;
}

结果是

103.381 97.1031 106.928 114.18 120.802 98.2669 114.038 106.057 126.741 136.836

125.589 124.903 123.564 102.781 125.09 71.5134 89.9109 92.4751 184.371 101.023

162.256 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 按任意键继续。. .

4

1 回答 1

3

不应该

    *(path + tid * steps + i) = S;

代替

    *(path+tid+i)=S;

?

您的版本有竞争条件 - 不同的线程正在写入相同的内存元素

upd:对,@talonmies 关于不良内存访问的观点是有效的——您的网格有 3 个块,每个块有 4 个线程,steps每个都处理元素,但分配的内存的大小较小。您可以将大小传递给内核并添加一个 check if(tid > size) return;,或者更改您的网格以更好地适应任务。

于 2013-09-09T15:41:26.460 回答