2016-08-01 55 views
0

我目前正在通过pycuda/cuda在GPU上编程一些数值方法,并正在编写我自己的内核。在某些时候,我需要估计至少1000个耦合ODE的误差。我不想复制超过1000个条目的几个向量,所以我创建了一个基本的最大功能的内核(在帖子的底部)。这些%(T)s和%(N)s是我在运行时所做的字符串替换,这对于这个问题应该是不相关的(T代表复杂的数据类型,N代表耦合的ODE的数量)。没有线程的GPU内核块大小/网格大小

我的问题是:没有必要进行并行计算,所以我不使用线程。当我在python中调用这个函数时,我应该指定什么是块大小或网格大小?

 __global__ void get_error(double *max_error,%(T)s error_vec[1][%(N)s]) 
    { 
     max_error[0]=error_vec[0][0].real(); 
     for(int ii=0;ii<%(N)s;ii=ii+1) 
     { 
      if(max_error[0] < error_vec[0][ii].real()) 
      { 
       max_error[0]=error_vec[0][ii].real(); 
      } 
     } 
     return; 
    } 
+2

1的块大小和1的网格大小会让你正好在GPU上执行一个线程 –

+0

@RobertCrovella谢谢,即使我没有任何变量链接到threadId,gpu将使用一个线程执行? – malxmusician212

+1

正确。相信你的知识(不管它可能是什么)作为C/C++程序员。 –

回答

1

在内核启动时,将在GPU上启动的线程总数等于为启动指定的网格大小和块大小的乘积。

这两个值都必须是正整数,因此这两个值的唯一可能组合是1,1来创建单个线程的启动。

CUDA内核不需要对内建变量进行任何特定引用(例如blockIdx,threadIdx等),但通常这样做是为了区分线程间的行为。在只有一个线程被启动的情况下,没有特别的理由使用这些变量,并且没有必要这样做。

只有一个线程的CUDA内核启动不是完成工作的高性能方法,但可能存在特定情况,方便这样做并且不会对整个应用程序产生显着的性能影响。

对于我而言,你提出的内核为什么不能作为线程并行内核来重构(它似乎在执行max-finding reduction),但这似乎与你的问题是分开的。

+0

您究竟能够平行找到最大值? – malxmusician212

+0

基本算法被称为并行压缩,并且[已有文档记载](http://developer.download.nvidia.com/assets/cuda/files/reduction.pdf)。为了说明的目的,大多数处理假定还原操作是所有元素的总和,但找到所有元素的最大值(或所有元素的最小值)的过程仅仅是微不足道的。 [这里](http://stackoverflow.com/questions/25195874/cuda-using-grid-strided-loop-with-reduction-in-shared-memory)是一个讨论最大发现减少的'cuda'标记问题。 –

+0

真棒,非常感谢@RobertCrovella! – malxmusician212