Cuda 螺纹及;块配置要求

Cuda 螺纹及;块配置要求,cuda,Cuda,我正在开发一个程序,在这个程序中我调用一个输入随机二进制数的函数。 总数量将在运行时提供,例如:1000或10,00000。。 在生成随机数之后,我需要使用计数器计算0的总数和1的总数。 我有以下疑问: 我应该分配多少线程、块和网格 我需要2D线程,还是只能使用1D线程 函数线程将在其中执行什么操作,我觉得它应该检查特定值是1还是0这听起来正确吗 我应该如何使用扭曲或平铺方法 我猜这可能是一个家庭作业问题,尤其是基于你发布的唯一一个问题 有多少线程/块/网格?这个问题的答案取决于你的线程策略。每

我正在开发一个程序,在这个程序中我调用一个输入随机二进制数的函数。 总数量将在运行时提供,例如:1000或10,00000。。 在生成随机数之后,我需要使用计数器计算0的总数和1的总数。 我有以下疑问:

  • 我应该分配多少线程、块和网格
  • 我需要2D线程,还是只能使用1D线程
  • 函数线程将在其中执行什么操作,我觉得它应该检查特定值是1还是0这听起来正确吗
  • 我应该如何使用扭曲或平铺方法

  • 我猜这可能是一个家庭作业问题,尤其是基于你发布的唯一一个问题

  • 有多少线程/块/网格?这个问题的答案取决于你的线程策略。每条线都会做什么?对于产生大量输出的问题,如图像处理或矩阵乘法,常见的线程策略是分配每个线程执行创建一个输出点的工作。但是这个问题只产生少量的输出值(看起来是2),属于一类问题,包括约化、流压缩和直方图。这些问题通常分两步解决(可能是两个内核…),一个常见的线程策略(至少在第一步或内核中)是为每个输入点分配一个线程。但也请参见我对下面第2条的回答。一旦知道需要多少线程,通常会选择每个块的一些线程数,如256或512(绝对使用2的幂),然后创建足够的块,使每个块的线程数乘以块数等于或大于问题大小(本例中的输入点数)
  • 二维还是一维?您的问题本质上并不是二维的,因此一维线程网格是一个合理的起点。但是,在1D线程网格中,可以在网格中创建的最大线程数限制为所使用GPU的最大网格X维度乘以每个块的线程数。这些数字通常类似于65535和1024,因此在输入点的大约64M个元素之后,线程就会用完。在这一点上,转换为使用2D网格结构并不困难,这将增加可能的线程数量,使其超过GPU一次可以处理的大小。但是,另一种策略不是切换到二维线程块网格,而是保留一维线程块网格,但让每个线程处理多个输入点/元素,可能在内核代码中使用循环。例如,如果您的循环最多可以处理512个元素,那么65535x1024x512应该涵盖您的问题大小。对于这类问题,这也是一种方便的线程策略,因为线程可以保留其创建的中间结果(到目前为止的1和0计数)的本地副本,而不会干扰或与其他线程同步
  • 基于上述内容,我的建议是,单个线程将执行一个循环,循环的每个过程将查看一个元素,并更新包含1和0计数的局部变量。这将是两部分算法的第一部分。第二部分则必须收集这些中间结果。您需要考虑一下第二部分将如何收集第一部分的结果。例如,在内核完成时,您可能希望将中间结果存储回全局内存
  • 翘曲/瓷砖?翘曲是指将线程分组为32个线程的执行单元。这将自动为您实现。您应该安排您的算法,以便在从全局内存读取值(或将值写入全局内存)时,每个线程在连续的连续块中读取(或写入)。也就是说,线程0从位置0读取,线程1从下一个位置读取,等等。如果您在线程中没有执行任何异常操作,这或多或少会自动发生。cudaMalloc创建的数据存储将正确对齐,如果您的数组索引策略类似于[thread_number],那么您将在整个warp中对齐并合并访问,这是为了获得GPU的良好速度。平铺是指组织数据访问以强调局部性的过程,这通常对依赖缓存的体系结构有利。如果你能很好地整合内存,你就不会太依赖缓存了

  • 如果您可以抽出时间,那么这是一个非常可读的文档,它将向您介绍好的GPU编程所需的基本概念。英伟达网站上也有2小时内可以覆盖的重要材料。此外,它可以用最少的编码工作(在C++中)方便地处理类似的问题,但我猜这超出了您现在尝试的范围。

    当使用(3)中描述的循环技术时,您可能需要特别注意获得(4)中描述的合并内存访问。1)@robert,我很理解这一部分。我将以一种形成更多扭曲的方式获取线程,并将线程与块相乘,以获得比我输入的值更大的值。2) 实际上我不明白,大约65535*1024*512?3) 对于结果的中间保存,_syncthreads()可以吗?但还是不懂,用线循环??我很困惑,我只想使用1D,那么我应该如何处理这个问题;我应该为1D中的256个线程配置blockDim(256,1)的blocksize吗?我读过这本书,但没有找到解决这个问题的方法,…请帮助我..65535*1024是1D网格中的最大线程数,至少对于某些GPU是这样。如果每个线程包含一个循环,例如while(not_done){process other input element},并且如果您的循环最多可以处理512个点,那么每个线程可以处理512个点和512个点