我尝试使用CUDA执行贝塞尔函数(例如J0(x))。 继承人公式 CUDA上的贝塞尔函数在某个epsilon内
我试图得到一些ε值内的结果。因此,这里的代码
__device__ void Bessel_j0(int totalBlocks, int totalThreads, float z, float epsilon, float* result){
int n = 1;
*result = 0;
bool epsilonFlag = true;
int idx_start;
int idx_end;
while(epsilonFlag == true){
initThreadBounds(&idx_start, &idx_end, n, totalBlocks, totalThreads);
float a_k;
for (int k = idx_start; k < idx_end; k++) {
a_k = m_power((-0.25 * z * z), k)/(m_factorial(k) * m_factorial(k));
*result += a_k;
}
if(a_k < epsilon){
epsilonFlag = false;
}
n++;
}
}
__global__ void J0(int totalBlocks, int totalThreads, float x, float* result){
float res = 0;
Bessel_j0(totalBlocks, totalThreads, 10, 0.01, &res);
result[(blockIdx.x*totalThreads + threadIdx.x)] = res;
}
__host__ void J0test(){
const int blocksNum = 32;
const int threadNum = 32;
float *device_resultf; //для устройства
float host_resultf[threadNum*blocksNum] ={0};
cudaMalloc((void**) &device_resultf, sizeof(float)*threadNum*blocksNum);
J0<<<blocksNum, threadNum>>>(blocksNum, threadNum, 10, device_resultf);
cudaThreadSynchronize();
cudaMemcpy(host_resultf, device_resultf, sizeof(float)*threadNum*blocksNum, cudaMemcpyDeviceToHost);
float sum = 0;
for (int i = 0; i != blocksNum*threadNum; ++i) {
sum += host_resultf[i];
printf ("result in %i cell = %f \n", i, host_resultf[i]);
}
printf ("Bessel res = %f \n", sum);
cudaFree(device_resultf);
}
int main(int argc, char* argv[])
{
J0test();
}
当我运行出现黑屏和Windows说,nVidia驱动没有回应,并恢复它。在控制台输出中,host_resultf
数组中只有零。怎么了?我怎样才能执行正确的功能,以在一些eps内?
您的程序执行时间过长,而您正在点击Windows TDR事件。这会卸载停止程序执行的GPU驱动程序。你应该看看你的程序是否有逻辑错误导致它花费很长时间,否则看看你是否可以缩短内核执行。您也可以尝试在CUDA GPU不是在Windows下运行显示器的WDDM GPU的机器上运行它。在您点击Windows TDR事件之前,在WDDM GPU上运行的内核被限制在大约2秒的执行时间内。 – 2013-04-07 14:56:11
请注意,CUDA库已经提供了第一类贝塞尔j0,j1,jn,以及第二类贝塞尔函数y0,y1,yn。 – njuffa 2013-04-07 17:42:03
@njuffa是的我知道了,但我有我自己做的任务-_- – DanilGholtsman 2013-04-07 18:04:42