我有一个奇怪的行为在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()
,但它没有奏效。
请问有人可以帮忙吗?
非常感谢
无论这个问题,我建议你开始接受对你有帮助的答案。请参阅[about](http://stackoverflow.com/about)页面。 – 2013-03-14 16:51:24
看起来像'matrice [index] = matrice [index - nbreSimulation] * ...'可能存在并发访问问题,如果有一个线程对应于'index - nbreSimulation' - 该线程可能会在之前运行或在对应于'index'的线程之后。但我不认为这只能解释矩阵中的一些值被填充。它可能只是矩阵上的索引问题。你有没有试过用'cuda-memcheck'运行代码?它可能会显示一些可能提供线索的超出范围的索引。我不知道'__synchronize()'调用,也许你的意思是'__syncthreads()'? – 2013-03-14 16:56:09
谢谢你的帮助。是的,我犯了一个错误,它是__syncthreads()。在我的代码中,一个粒子路径是由一个线程模拟的,那么关于并发访问通常应该是可以的。我无法解释这种奇怪的行为。乘法触发一个奇怪的结果.. – ALFRAM 2013-03-14 17:03:39