![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
并行计算
文章平均质量分 74
王莽v2
做一条有梦想的咸鱼
展开
-
torch中tensor的in-place操作
在PyTorch中,张量(tensor)的行为与numpy数组类似,但也有它们自己的特点。下面是对您提供的两段代码的解释:对于 Y = Y + X:这里发生的是一个非就地(out-of-place)操作。Y + X 创建了一个新的张量来存储加法的结果,然后这个新的张量被赋值给变量Y。因此,Y的id会改变,因为它现在引用了一个新的对象。所以,id(Y) == before 的结果将是 False。对于 X += Y 或者 X.add_(Y):这里发生的是一个就地(in-place)操作。原创 2024-04-29 10:36:10 · 187 阅读 · 0 评论 -
7.3 CONSTANT MEMORY AND CACHING
因此,当warp中的所有线程访问相同的恒定内存变量时,就像M的情况一样,缓存可以提供大量的带宽来满足线程的数据需求。为了减轻内存瓶颈的影响,现代处理器通常使用片上缓存存储器或缓存,以减少需要从主存储器(DRAM)访问的变量数量,如图7.9所示。更好的是,所有线程都以相同的顺序访问M元素,从M[0]开始,并通过图7.6.中for循环的迭代一次移动一个元素。请注意,这是一个特殊的内存复制函数,它通知CUDA运行时,在内核执行期间,复制到常量内存的数据不会更改。然后,变量的值将从缓存中提供,无需访问DRAM。原创 2024-01-09 17:47:36 · 372 阅读 · 0 评论 -
7.2 1D PARALLEL CONVOLUTION—A BASIC ALGORITHM
为了简单起见,我们假设Mask_Width是一个奇数,卷积是对称的,即Mask_Width是2*n + 1,其中n是整数。因此,在if声明中,它们都将是一些不同的决定。计算P[0]的线程将跳过大约一半的乘法累积语句,而计算P[1]的那个会少跳过一次,以及以此为由。我们假设1D卷积内核收到五个参数:指向输入数组N的指针,指向输入掩码M的指针,指向输出数组P的指针,掩码Mask_Width的大小,以及输入和输出数组宽度的大小。原创 2024-01-09 17:01:10 · 395 阅读 · 0 评论 -
Parallel patterns: convolution —— An introduction to stencil computation
应该清楚的是,P[0]的计算将涉及两个缺失的N个元素,在本例中,这两个元素都将被假定为0。我们使用5元素掩码M的事实意味着每个P元素是由对应位置的N个元素的加权和生成的,左边是两个N个元素,右边是两个N个元素。例如, P[2] 的值生成为 N[0](即 N[2-2])到N[4](即N[2+2])的加权和。在图7.1中,P[i] 的计算可以看作是从 N[i-2] 开始的N子数组和M数组之间的内积。也就是说,P[3] 的值是N[1](即N[3-2])通过N[5](即N[3 + 2])的加权和。原创 2024-01-09 16:29:25 · 1058 阅读 · 0 评论 -
CUDA并行计算对精度的影响
并行归约(Parallel Reduction): 在并行计算中,例如在进行归约操作时,如果不小心处理浮点数相加可能导致累积误差。在一些科学计算应用中,数值精度是非常关键的,因此在选择并行算法和优化技术时需要仔细考虑。在这个简单的向量相加的CUDA内核中,如果输入数组 a 和 b 中包含极小或极大的浮点数,那么在并行计算中可能会由于浮点数舍入误差而引入一些微小的差异。数据依赖性: 并行计算中,如果存在数据依赖性,即某个计算的结果依赖于其他计算的结果,可能会导致数值不稳定性。虽然这在串行计算中也存在,但。原创 2024-01-09 15:24:17 · 510 阅读 · 0 评论 -
5.5 THREAD GRANULARITY
如图5.17所示,相邻 tile 中两个P元素的计算使用相同的 M 行。使用原始的 tile 算法,相同的M行被分配给生成这两个P tile 的两个块冗余加载。有时,在每个线程中投入更多工作并使用更少的线程是有利的。图5.17说明了矩阵乘法的这种机会。图5.6中的tile算法,使用一个线程来计算输出P矩阵的一个元素。正如我们在上一节中讨论的,可以在每个SM上运行的块数量可能会减少。在实践中,组合多达四个相邻的水平块来计算相邻的水平tile,显著提高了大型(2048x2048或更多)矩阵乘法的性能。原创 2024-01-09 14:07:39 · 376 阅读 · 0 评论 -
5.4 DYNAMIC PARTITIONING OF RESOURCES
如果每个线程块包含256个线程,则对1536个线程插槽进行分区并分配给6个线程块。他们可以执行许多线程块,每个线程很少,也可以执行几个线程块,每个线程有很多线程。如果每个线程块由512个线程组成,则1536个线程插槽被分区并分配给三个块。阅读器参考CUDA占用计算器[NVIDIA],这是一个可下载的Excel工作表,根据内核对资源的使用情况,计算每个SM上运行的线程的实际数。通过在块之间动态分区寄存器,如果需要很少的寄存器,SM可以容纳更多的块,如果需要更多的寄存器,则可以容纳更多的块。原创 2024-01-09 13:57:25 · 377 阅读 · 0 评论 -
5.3 WARPS AND SIMD HARDWARE
我们现在把注意力转向线程执行中可能限制性能的方面。回想一下,启动CUDA内核会生成一个线程网格,该网格被组织为两级层次结构。在顶层,网格由一维、二维或三维块阵列组成。在底层,每个块依次由一维、二维或三维线程阵列组成。在第3章,可扩展并行执行中,我们看到块可以以任何相对的顺序执行,这允许跨不同设备的透明可扩展性。然而,我们没有过多说明每个块内线程的执行时间。从概念上讲,人们应该假设块中的线程可以相互之间以任何顺序执行。在具有相位的算法中,每当我们想确保所有线程在开始下一阶段之前都已完成执行的通用阶段时,就应原创 2024-01-09 12:50:14 · 840 阅读 · 0 评论 -
5.2 MORE ON MEMORY PARALLELISM
例如,如果有更多的元素,M[16]和M[17]将存储在通道0的0bank中,M[18]和M[19]将存储在通道1的0 bank中,等等。通道和bank的地址是,阵列的前八字节(M[0]和M[1])存储在通道0的bank0中,接下来的八字节(M[2]和M[3])存储在通道1的bank0中,接下来的八字节(M[4]和M[5])存储在通道2的bank0中,接下来的八字节(M[6]和M[7])存储在通道3的bank0中。也就是说,在进入通道1的0bank之前,我们只分配足够的元素来充分利用通道0的DRAM突发。原创 2024-01-09 11:29:35 · 768 阅读 · 0 评论 -
*5.1 Global Memory Bandwidth
并行程序的执行速度可能因计算硬件的资源限制而有很大差异。虽然管理并行代码和硬件资源约束之间的交互对于在几乎所有并行编程模型中实现高性能很重要,但这是一种实用技能,最好通过为高性能设计的并行编程模型中的实践练习来学习。在本章中,**我们将讨论CUDA设备中的主要资源约束类型,**以及它们如何影响内核执行性能[Ryoo 2008JICUDA C最佳实践]。为了实现他/她的goals,程序员通常必须找到达到高于应用程序初始版本所需性能水平的方法。。原创 2024-01-09 10:17:24 · 373 阅读 · 0 评论 -
4.7 MEMORY AS A LIMITING FACTOR TO PARALLELISM
然后,应用程序可以将这个数字除以驻留在每个SM中的目标线程数,以确定可以在kerel中使用的寄存器数量。因此,从1536开始,下一个较小的线程数量将是1024,这表明可以同时驻留在每个SM中的线程减少1/3。为了说明内核的寄存器使用与设备可以支持的并行性水平之间的交互,假设在当前一代设备D中,每个SM可以容纳多达1536个线程和16,384个寄存器。通常,每个线程需要的资源越多,每个SM中可以驻留的线程就越少,同样,在整个设备中并行运行的线程也就越少。不幸的是,图4.16中的内核不支持这一点。原创 2024-01-08 23:39:00 · 882 阅读 · 0 评论 -
4.6 BOUNDARY CHECKS
通过更改图4.14中的示例至3×3 M、N和P矩阵,图4.18创建了矩阵的宽度为3,不是tile宽度(2)的倍数。我们看到thread1,0和thread1,1试图访问不存在的M元素Ms3,0和Ms3.1,而thread0.1和thread1,1试图访问N0,3和N1,3,它们不存在。通过使用共享内存,可以显著减少对全局内存的访问次数,从而减少内存延迟,并提高整体的内存带宽效率。的选择是一个权衡的结果,它需要考虑硬件的限制、内存的效率和算法的并行性。:更小的瓷砖允许更细粒度的线程管理和更高的线程并行度。原创 2024-01-08 23:24:29 · 900 阅读 · 0 评论 -
4.5 A TILED MATRIX MULTIPLICATION KERNEL
Thready.tx的循环进度如图4.17所示,M和N元素沿箭头的访问方向,箭头标有k,第12行的循环变量。第14行中的屏障__syncthreads()确保所有线程在进入下一个迭代并从下一个tile加载元素之前,所有线程都已完成使用共享内存中的M和N元素。这很重要,因为块中的所有线程都必须能够访问加载的M和N元素由同行进入Mds和Nds,以便他们可以使用这些值来满足他们的输入需求。图4.16中的第8行。.回顾图4.14中的例子,由block1,0的线程1.0计算的P元素的y索引,”为1*2+ 0=2。原创 2024-01-08 23:01:45 · 1002 阅读 · 0 评论 -
4.4 TILING FOR REDUCED MEMORY TRAFFIC
在每个阶段,一个块中的所有线程都协作,将M的tile和N的tile加载到共享内存中。在第1阶段开始时,block0.0的四个线程协同将M的tile加载到共享内存中:threde0.0将M0.0加载到MdS0,0,thread0.1加载M0.1到Mds0.1,thread1.o加载M1,o加载到Mds1.0,thread1,1将M1.1加载到Mds1,1,如图4.15中第二列所示。在每个阶段,相同的Mds和Nds用于在相位中保存M和N元素的子集,从而允许更小的共享内存为global内存的大部分访问提供服务。原创 2024-01-08 20:26:43 · 887 阅读 · 0 评论 -
3.9 EXERCISES
如果该学生声称他们使用32×32线程块来执行1024×1024矩阵的乘法,并且每个线程块中的每个线程都计算结果矩阵的一个元素,那么他们的配置与CUDA设备的硬件限制不符。具体来说,他们的线程块设置超过了每个块允许的最大线程数,因为32×32等于1024,而设备的限制是每个块最多512个线程。由于您想要使用正方形的线程块,因此您应该选择一个线程块的尺寸,其边长是1024的平方根。这个信息对于理解内核如何在多个SM上调度是有用的,但它并不影响线程块大小的选择,只要线程块的大小遵守了每个块的最大线程数限制。原创 2024-01-08 19:54:30 · 892 阅读 · 0 评论 -
*4.3 CUDA MEMORY TYPES
CUDA设备包含几种类型的内存,可以帮助程序员提高计算到全局内存的访问率,从而实现高执行速度。图4.6显示了这些CUDA设备内存。全局内存和恒定内存出现在图片的底部。主机可以通过调用API函数来写入(W)和读取(R)这些类型的内存。我们已经在第2章中引入了全局内存,数据并行计算。设备可以写入和读取全局内存。恒定内存支持设备短延迟、高带宽只读访问。寄存器和共享内存,如图4.6所示,是片上内存。驻留在这些类型内存中的变量可以以高度并行的方式以非常高速的方式访问。寄存器分配给单个线程;每个线程只能访问自己的寄原创 2024-01-08 19:13:17 · 862 阅读 · 0 评论 -
4.2 MATRIX MULTIPLICATION
因此,块(0,0)中的线程(0,0)成功计算了M的0行和N的0列之间的内积,并将结果存入P0.0。循环的每个迭代都从M的行访问一个元素,从N的Coith列访问一个元素,将两个元素乘以一起,并将乘积累积到Pvalue中。我们现在把注意力转向N。如图4.3所示,第Col列的开头元素是第0行的第Col元素,即N[Col]。回想一下,M被线性化成一个等价的1D数组,其中M的行一个接一个地放置在内存空间中,从0行开始。(P中的小方块)是由M的Row行(在M中显示为水平条带)和由N的Col列(在N中显示为垂直条带)原创 2024-01-08 18:14:38 · 583 阅读 · 0 评论 -
4.1 Importance of Memory Access Efficiency
虽然我们涵盖的范围是一个非常好的开始,但到目前为止,我们学到的CUDA内核可能只能实现底层硬件潜在速度的一小部分。我们可以通过计算图3.8中图像模糊内核代码中执行次数最多的部分的预期性能水平来说明内存访问效率的影响。计算与全局内存比为1.0时,图像模糊内核的执行将受到操作数(例如,in[] 的元素)传递到GPU的速度的限制。总的来说,在过去的几代设备中,所需的比率一直在增加,因为计算吞吐量比内存带宽增长得更快。在当今的高端设备中,在本章中,您将学习使用不同的内存类型来提高CUDA内核的执行效率。原创 2024-01-08 16:57:12 · 812 阅读 · 0 评论 -
3.8 SUMMARY
Kerel执行配置参数定义了grid及其块的尺寸。blockldx和threadldx中的唯一坐标允许网格的线程识别自己及其数据域。程序员有责任在内核函数中使用这些变量,以便线程能够正确识别要处理的数据部分。对于每个内核,其中一个或多个资源限制可以成为同时驻留在CUDA设备中的线程数量的限制因素。**线程被分配给SM,以便逐个块执行。**每个CUDA设备对每个SM的可用资源量施加了潜在的不同限制。,从而实现CUDA应用程序的透明可扩展性。一旦一个块被分配给一个SM,它就会被进一步分割成warp。原创 2024-01-08 16:36:26 · 352 阅读 · 0 评论 -
3.7 THREAD SCHEDULING AND LATENCY TOLERANCE
这个数字在8块限制范围内,是一个很好的配置,因为它将允许我们在每个SM中拥有完整的线程容量,并允许围绕长延迟操作调度最大数量的warp。warps的大小是特定于实现的。为了使内核保持透明的可扩展性,不同块中的线程相互同步的简单方法是终止内核,并在同步点后为活动启动一个新的内核。一个合理的问题是,如果一个SM在任何时候都只能执行一小部分,那么为什么我们需要在SM中有这么多的warp。正如我们将在第4章“内存和数据局部性”中解释的那样,在确定最合适的块尺寸时,还必须考虑寄存器和共享内存等其他资源的使用。原创 2024-01-08 16:21:12 · 918 阅读 · 0 评论 -
3.6 QUERYING DEVICE PROPERTIES
该应用程序通常需要查询底层硬件的可用资源和功能,以便利用能力更强的系统,同时补偿能力较差的系统。这些GPU是默认的图形单元,提供基本的功能和硬件资源,为现代基于Windows的用户界面执行最小的图形功能。这一弱点将是主机代码遍及所有可用设备,查询其资源和功能,并选择具有足够资源的设备来令人满意地执行应用程序的原因。正如我们之前所讨论的,一些设备只有少量的SM(例如tWO),有些设备的SM数量要多得多(例如30)。此外,设备的时钟频率在。因此,应该查询可用的设备,并确定每个块中允许足够数量线程的设备。原创 2024-01-08 15:53:00 · 757 阅读 · 0 评论 -
3.5 RESOURCE ASSIGNMENT
在同时执行8个块所需的一种或多种资源类型短缺的情况下,CUDA运行时会自动减少分配给每个SM的块数量,直到其合并资源使用量低于限制。由于可以分配给每个SM的SM数量有限,并且可以分配给每个SM的块数量有限,因此可以在CUDA设备中主动执行的块数量也有限。大多数网格包含的块比这个数字多得多。这可以是6个块,每个256个线程,3个块,每个512个线程,以此为由之。如果CUDA设备有30个SM,并且每个SM可以容纳多达1536个线程,则该设备可以同时拥有多达46,080个线程,同时驻留在CUDA设备中进行执行。原创 2024-01-08 15:36:23 · 375 阅读 · 0 评论 -
3.4 SYNCHRONIZATION AND TRANSPARENT SCALABILITY
他们都可以去不同的商店买自己的衣服。对于if-then-else语句,如果每个路径都有_syncthreads()语句,则块中的所有线程要么执行then-path,要么所有线程都执行else-path。例如,移动处理器可能会以极低的功耗缓慢执行应用程序,而桌面处理器可能会以更高的速度但更高的功耗执行相同的应用程序。在一个只有少数执行资源的低成本系统中,人们可以同时执行少量块,在图3.11的左侧被描绘成一次执行两个块。在具有更多执行资源的高端实现中,可以同时执行大量块,在图3.11的右侧一次显示为四个块。原创 2024-01-08 15:08:03 · 833 阅读 · 0 评论 -
3.3 IMAGE BLUR: A MORE COMPLEX KERNEL
在案例1中,左上角的像素被模糊了。在执行嵌套循环期间,九次迭代的CurRow和CurCol值为(-1,-1)、(-1,0)、(-1,1)、(0,-1)、(0,0,)、(0,1)、(1,-1)、(1,0)和(1,1)。举例来说,计算(25,50)输出像素的九个像素的坐标是(24,49),(24,50),(24,51),(25,49),(25,50),(25,51),(26,49),(26,50)和(26,51)。在本章中,我们将使用简化的方法,取周围像素的NxN补丁的简单平均值,包括我们的目标像素。原创 2024-01-08 14:12:44 · 920 阅读 · 0 评论 -
3.2 MAPPING THREADS TO MULTIDIMENSIONAL DATA
我们需要x方向的5个块和y方向的4个块,结果是5个x 4=20个块,如图3.2所示,沉重的线条标志着block的边界。请注意,我们在x方向有4个额外的线程,在y方向有2个额外的线程——也就是说,我们将生成80×64个线程来处理76×62像素。与此同时,网格的尺寸取决于图片的尺寸。为了处理2000×1500(3百万像素)的图片,我们将生成11,750个块——x方向的125个,y方向的94个。图3.3说明了4×4矩阵M如何线性化为16个元素的一维数组,首先是0行的所有元素,然后是第1行的四个元素,以此为例。原创 2024-01-08 13:00:55 · 807 阅读 · 0 评论 -
3.1 CUDA Thread Organization
与主机代码中的dim3变量不同,内核函数中这些变量的名称是CUDA C规范的一部分,不能更改——即内核中的gridDim和blockDim总是反映网格和块的维度。在块中,blockldx.x值从0到gridDim.x-1,blockldx.y值从O到gridDim.y-1,blockldx.z值从O到gridDim.z-1。熟悉C中结构使用的读者会意识到,这种1D配置的“速记”惯例利用了x字段是dim3结构gridDim(x,y,z)和blockDimlx,y,z)的第一个字段这一事实。原创 2024-01-07 23:37:52 · 823 阅读 · 0 评论 -
2.8 EXERCISES
如果我们想从主机数组h_A(h_A是源数组元素0的指针)复制3000字节的数据到设备数组d_A(d_A是目标数组元素0的指针),那么CUDA中此数据副本的适当APl调用是什么?如果我们想分配一个由n个浮点元素组成的数组,并有一个foating-point指针变量d_A来指向分配的内存,那么cudaMalloc()调用的第一个参数的适当表达式是什么?如果我们想在CUDA设备全局内存中分配一个v整数元素的数组,对于cudaMalloc调用的第二个参数,适当的表达式是什么?这可以减少一些重复性的代码声明。原创 2024-01-07 18:37:53 · 823 阅读 · 0 评论 -
2.7 SUMMARY
本章提供了CUDA C编程模型的快速、简化的概述。CUDA扩展C语言以支持并行计算。在本章中,我们讨论了这些扩展的基本子集。原创 2024-01-07 17:48:23 · 326 阅读 · 0 评论 -
2.6 KERNEL LAUNCH
2.12和2.15共同说明了一个简单的CUDA程序,该程序由主机代码和设备内核组成。该代码是硬接的,每个线程块使用256个线程。然而,使用的线程块的数量取决于向量(n)的长度。请注意,所有线程块都在矢量的不同部分上运行。这为CUDA内核提供了硬件执行速度的可扩展性,也就是说,相同的代码在小型GPU上以较低的速度运行,并且在较大的GPU上速度更高。真正的应用程序通常有内核,与处理的数据量相比,需要更多的工作,这使得额外的开销是值得的。重要的是要再次指出,使用向量加法示例是为了它的简单性。原创 2024-01-07 17:40:41 · 363 阅读 · 0 评论 -
2.5 KERNEL FUNCTIONS AND THREADING
一般来说,线程的数量由于硬件效率的原因,线程块每个维度的线程应该是32的倍数。每个块中的第一个线程在其threadldx.x变量中具有值 0,第二个线程具有值1,第三个线程具有值2,等。对于给定的网格,块中的线程数在内置的blockDim变量中可用。在图2.11中,第一个块中的所有线程在其blockldx.x变量中都有值0,第二个线程块中的值为1,以此等。这种内核函数将在设备上执行,并且只能从主机代码调用,除非在支持动态并行的CUDA系统中,正如我们将在第13章CUDA动态并行性中解释的那样。原创 2024-01-07 17:23:07 · 1069 阅读 · 0 评论 -
2.4 DEVICE GLOBAL MEMORY AND DATA TRANSFER
相反的方向也是如此。然后,它从设备内存中释放d_A、d_B和d_C的内存,这是通过调用cudaFree函数完成的。第四个参数表示副本中涉及的内存类型:**从主机内存到主机内存,从主机内存到设备内存,从设备内存到主机内存,以及从设备内存到设备内存。在图2.6中,vecAdd函数的第1部分和第3部分需要使用CUDA API函数为A、B和C分配设备内存,将A和B从主机内存传输到设备内存,在矢量添加结束时将C从设备内存传输到主机内存,并为A、B和C释放设备内存。d_A、d_B和d_C中的地址是设备内存中的地址。原创 2024-01-07 16:41:08 · 786 阅读 · 0 评论 -
2.3 A VECTOR ADDITION KERNEL
在我们所有的示例中,每当需要区分主机和设备数据时,我们都会在主机处理的变量名称前加上“h_”和由设备处理的变量名称“d_”,以提醒自己这些变量的预期用途。修订后的函数的细节,以及编写内核函数的方法,将在本章的其余部分中展示。形式参数h_A、h_B和h_C是通过引用传递的,因此函数读取h_A、h_B的元素,并通过参数指针A、B和C写入h_C的元素。在图2.5中,传递数组名称A作为函数调用vecAdd的第一个参数,使函数的第一个参数h_A指向A的第0个元素。因此,函数主体中的h_A[i]可用于访问A[i]。原创 2024-01-07 15:39:25 · 893 阅读 · 0 评论 -
2.2 CUDA C PROGRAM STRUCTURE
当内核的所有线程完成执行时,相应的网格终止,执行继续在主机上,直到启动另一个内核。主机代码是直接的ANSI C代码,使用主机的标准C/C++编译器进一步编译,并作为传统的CPU进程运行。在没有可用的硬件设备或可以在CPU上适当执行内核的情况下,也可以选择使用MCUDA[SSH 2008]等工具在CPU上执行内核。线程由程序的代码、正在执行的代码中的特定点及其变量和数据结构的值组成。可以使用源级调试器通过一次执行一个语句来监控线程的进度,查看接下来将执行的语句,并在执行过程中检查变量和数据结构的值。原创 2024-01-07 14:25:40 · 377 阅读 · 0 评论 -
2.1 DATA PARALLELISM
如果我们认为输入是组织为RGB值数组I的图像,输出是亮度值的相应数组O,我们得到图中所示的简单计算结构。为了渲染图像,每个像素的r、g、b值用于计算像素的总强度(亮度)以及混合系数(x、y、1-y-x)。在RGB表示中,图像中的每个像素都存储为(r,g,b)值的元组。也就是说,对于每个像素,r、g和b值表示渲染像素时红色、绿色和蓝色光源的强度(0为暗,1为全强度)。例如,在分子动力学模拟器中,自然任务列表包括振动力、旋转力、非键合力的邻接识别、非键合力、速度和位置,以及基于速度和位置的其他物理属性。原创 2024-01-07 12:30:10 · 375 阅读 · 0 评论 -
1.8 ORGANIZATION OF THE BOOK
第11章,并行模式:合并排序,介绍合并排序,以及动态输入数据识别和组织。然后,它涵盖了涉及的思维过程:(1)识别要并行化的应用程序部分,(2)隔离并行化代码使用的数据,使用APl函数在并行计算设备上分配内存,(3)使用APl函数将数据传输到并行计算设备,(4)开发将由并行化部分线程执行的内核函数,(5)启动并行线程执行的内核函数,以及(6)最终通过APl函数调用将数据传输回主机处理器。第20章,关于CUDA和GPU计算的更多信息,第21章,结论和展望,提供了总结性发言和大规模并行编程的未来展望。原创 2024-01-07 00:37:46 · 330 阅读 · 0 评论 -
1.7 OVERARCHING GOALS
即使我们有这样的工具,我们也怀疑对硬件有更多了解的程序员将能够以比没有硬件的程序员更有效地使用这些工具。相反,我们将教授基本的计算机架构知识,作为我们讨论高性能并行编程技术的一部分。尽管如此,实现这些目标仍需要大量技术知识,因此我们将在这本书中介绍不少并行编程的原则和模式[Mattson 2004]。我们无法涵盖所有内容,但是,我们选择了我们认为最有用和经过充分验证的技术来详细涵盖。,我们的方法不需要大量的硬件专业知识。而且,我们相信,一旦你发展正确的洞察力并以正确的方式进行,它就会变得容易。原创 2024-01-07 00:31:55 · 322 阅读 · 0 评论 -
1.6 PARALLEL PROGRAMMING LANGUAGES AND MODELS
由于CUDA让程序员明确控制这些并行编程细节,即使对于想要使用OpenMP和OpenACC作为主要编程界面的人来说,它也是一个很好的学习工具。因此,HPC中的并行程序员必须了解如何进行联合MPI/CUDA编程,该编程载于第18章,编程异构计算集群。OpenCL是一个标准化的编程模型,在OpenCL中开发的应用程序可以在所有支持OpenCL语言扩展和API的处理器上正常运行,而无需修改。那些熟悉OpenCL和CUDA的人知道,OpenCL的关键概念和功能与CUDA的关键概念和功能之间存在显著的相似性。原创 2024-01-07 00:28:37 · 348 阅读 · 0 评论 -
1.5 CHALLENGES IN PARALLEL PROGRAMMING
幸运的是,这些挑战中的大多数在过去是由研究人员解决的。跨应用程序域也有常见的模式,允许我们将从一个域派生的解决方案应用于其他域。这就是为什么我们将在重要的并行计算模式的背景下提出解决这些挑战的关键技术的主要原因。是什么让并行编程变得困难?我们将这些应用程序称为内存绑定,而不是计算绑定,后者受每字节数据执行的指令数量的限制。许多现实世界的应用程序需要处理具有不同特征的输入,例如不速或不可预测的数据速率,以及非常高的数据速率。首先,设计具有与顺序算法相同水平的算法(计算)复杂度的并行算法可能具有挑战性。原创 2024-01-06 00:29:11 · 347 阅读 · 0 评论 -
1.4 SPEEDING UP REAL APPLICATIONS
事实上,正如我们将在第20章《关于CUDA和GPU计算的更多信息》中讨论的那样,这些编程模型及其底层硬件仍在快速发展,以便能够对更大的应用程序进行高效并行化。请记住,通过单核CPU执行实现的加速水平也可以反映CPU对应用程序的适用性:在某些应用程序中,CPU性能非常好,因此使用GPU更难加快性能。另一方面,如果99%的执行时间在并行部分,则将并行部分加速100倍将应用程序执行减少到原始时间的1.99%。事实上,即使在并行部分进行无限的加速,也只能减少30%的执行时间,实现不超过1.43倍的加速。原创 2024-01-06 00:22:09 · 350 阅读 · 0 评论 -
1.3 WHY MORE SPEED OR PARALLELISM?
在可预见的未来,这些模拟将继续受益于计算速度的提高,即可以建模的生物系统的大小和可以在可容忍的响应时间内模拟的反应时间长度。虽然这样做的技术通常为一些每天使用此类应用程序的专家所熟知,但绝大多数应用程序开发人员可以从对这些技术的更直观的理解和实用工作知识中受益。我们可以期待在未来看到更多这些逼真的效果:碰撞会损坏你的车轮,玩家的驾驶体验会更逼真。毫无疑问,这些设备的未来版本将包含具有三维视角的传感器和显示器,结合虚拟和物理空间信息以提高可用性的应用程序,以及基于语音和计算机视觉的接口,需要更高的计算速度。原创 2024-01-06 00:15:42 · 382 阅读 · 0 评论