2013-03-14 42 views
0

我有一个奇怪的行为在CUDA中的问题。 我目前正在开发一个关于粒子轨迹的蒙特卡洛模拟,我正在做以下事情。CUDA和蒙地卡罗与定义的本地行为

我的粒子在给定日期t(n)的位置p(n)取决于我的粒子在前一日期t(n-1)的位置t(n-1)。事实上,假设值v(n)是从值p(n-1)计算出来的。这里是我的代码一个简单的例子:

__device__ inline double calculateStep(double drift, double vol, double dt, double randomWalk, double S_t){ 
    return exp((drift - vol*vol*0.5)*dt + randomWalk*vol*sqrt(dt))*S_t; 
}  

__device__ double doSomethingWhith(double v_n, ….) { 
    ... 
    Return v_n*exp(t)*S 
} 



__global__ myMCsimulation(double* matrice, double * randomWalk, int nbreSimulation, int nPaths, double drift, ……) { 


    double dt = T/nPaths; 
    unsigned int tid = threadIdx.x + blockDim.x * blockIdx.x; 
    unsigned int stride = blockDim.x*gridDim.x; 
    unsigned int index = tid; 
    double mydt = (index - nbreSimulation)/nbreSimulation*dt + dt; 

    for (index = tid; index < nbreSimulation*nPaths; index += stride) { 
    if (index >= nbreSimulation) 
    { 
    double v_n = DoSomethingWith(drift,dt, matrice[index – nbreSimulation]); 
    matrice[index] = matrice[index - nbreSimulation ] * calculateStep(drift,v_n,dt,randomWalk[index]); // 
    } 
...} 

最后的代码行:

matrice[index] = matrice[index - nbreSimulation ] * calculateStep(drift,v_n,dt,randomWalk[index]); 

让我填只有矩阵矩阵的计算的第二排。我不知道为什么。

当我通过改变代码行:

matrice[index] = DoSomethingWith(drift,dt, matrice[index – nbreSimulation]); 

我的矩阵,以及填补了和我有我所有的值改变,那么我能够找回matrice[index – nbreSimulation]。 我认为这是一个并发访问,但我不知道,我试过__syncthreads(),但它没有奏效。

请问有人可以帮忙吗?

非常感谢

+0

无论这个问题,我建议你开始接受对你有帮助的答案。请参阅[about](http://stackoverflow.com/about)页面。 – 2013-03-14 16:51:24

+0

看起来像'matrice [index] = matrice [index - nbreSimulation] * ...'可能存在并发访问问题,如果有一个线程对应于'index - nbreSimulation' - 该线程可能会在之前运行或在对应于'index'的线程之后。但我不认为这只能解释矩阵中的一些值被填充。它可能只是矩阵上的索引问题。你有没有试过用'cuda-memcheck'运行代码?它可能会显示一些可能提供线索的超出范围的索引。我不知道'__synchronize()'调用,也许你的意思是'__syncthreads()'? – 2013-03-14 16:56:09

+0

谢谢你的帮助。是的,我犯了一个错误,它是__syncthreads()。在我的代码中,一个粒子路径是由一个线程模拟的,那么关于并发访问通常应该是可以的。我无法解释这种奇怪的行为。乘法触发一个奇怪的结果.. – ALFRAM 2013-03-14 17:03:39

回答

1

我已经改变了我的代码的以下事情,现在它完美的作品。

if (index < nbreSimulation) { 
      matrice[index] = S0;  
      for (workingCol=1; workingCol< nPaths; workingCol++) { 
       previousMove = index; 
       index = index + nbreSimulation; 
        ................ 
       matrice[index] = calculateStep(drift,vol_int[index],dt,randomWalk[index], matrice[previousMove]);    } 
     } 
    } 
0

我曾尝试以下事情:

我已经声明了一个共享变量(double数组),其包含在每次迭代中计算出的值:无

__shared__ double mat[]; 

...... 
for (index = tid; index < nbreSimulation*nPaths; index += stride) { 
    ..... 
    mat[index] = computedValue; 
    ...... 
} 

成功。有没有人看到这个问题?