本地和全局大小对程序执行的影响 - OpenCl

时间:2017-01-24 11:22:13

标签: multithreading parallel-processing opencl

在阅读了很多关于全球工作规模和当地工作规模的定义后,我仍然不了解它们是什么以及它们是如何工作的。 我认为全局工作量确定将调用内核函数的次数,但是本地工作量是多少?

我认为本地工作大小决定了在同一时间内并行使用多少线程,但我真的是正确的吗?

本地大小是否为每个全局大小值执行一个内核程序的线程数?我的意思是当我们有全局大小= 1和本地大小= 1时,内核函数将被调用一次,只有一个线程将在它上面工作。 但是当我们有全局大小= 4096和本地大小(如果允许那么高)是1024那么我们有4096个内核函数调用,并且每个调用有1024个线程同时处理它?我是对的吗?

以下是我发现的一些示例代码: enter image description here

我的另一个问题是:本地大小变化如何影响该代码? 正如我所看到的那样明显地在global_id上工作,没有本地大小更改为更大的本地大小比假设1将影响执行该算法所花费的时间?

当我们在该算法中进行循环时,它是否会改变任何关于局部大小影响的东西?我们是否需要使用local_id来查看更改本地大小时的任何差异?

我在我的一些程序中测试了这一点,即使我只使用global_id改变了本地工作大小,也显着缩短了执行时间。 那么它是怎样工作的?我不明白。

提前谢谢!

1 个答案:

答案 0 :(得分:2)

  

我认为本地工作量确定了多少线程   在同一时间并行使用,但我真的是对吗?

正确但它是每个计算单位,而不是整个设备。如果计算单元多于本地线程组,则设备未完全使用。如果线程组多于计算单元但不是精确多个,则某些计算单元最后会等待其他计算单元。当两个值相等(或精确到多个)时,那么"多少次"完全占据所有ALUS非常重要。

例如,一个8核cpu可以定义8个计算单元(硬件多线程可能多+ 8个)。但价格相近的GPU可以拥有20到64个计算单元。然后,即使在单个计算单元内,许多线程组也可以在飞行中#34;没有明确调整,但是每个线程和每个计算单元的资源使用情况以及每个gpu可能会改变。

  

本地大小变化如何影响该代码?正如我所看到的那样清楚   在global_id上工作,没有本地的,因此本地大小更改为   比1更大的一个会影响执行它的时间   算法

可矢量化/可并行化的内核代码可以具有将线程分布到核心的GPU,核心的SIMD或者更广泛的SIMU计算单元的SIMD的优点。对于CPU,可以同时发出8个标量指令。对于GPU,它可能会达到数千个。因此,当您将本地大小减小到1时,您将并行线程问题的宽度限制为1 ALU,从而削弱了许多体系结构的性能。当您将本地大小设置得太大时,每个线程的资源会下降并且性能会受到影响。如果您不知道,opencl api可以为您调整本地大小,如果您为其参数设置null。

  

当我们在该算法中进行循环时,它是否会发生变化   关于当地规模影响的任何事情?我们需要使用吗?   local_id在更改本地大小时看到有什么不同吗?

对于旧的和静态的调度体系结构,建议使用展开步长大小等于基本SIMD宽度的宽度来进行循环展开。不,本地ID只是对其计算单元中的线程ID的查询,因此无需查询您是否需要它。

  

我在我的一些程序中测试过,即使我只使用它   global_id改变当地的工作规模让我明显缩短了   执行时间。那它是如何运作的?

如果内核需要疯狂的资源,你可以想到每个本地组有1个线程。如果内核不需要除立即值之外的任何资源,则应将其设为最大本地值。每个线程的资源分配(由于内核代码)很重要。新体系结构具有负载平衡,因此如果您让api选择最佳值,将来可能无关紧要。

为了保持所有ALU忙,调度程序每个核心发出多个线程,当一个线程正在等待内存操作时,另一个线程可以同时执行ALU操作。当资源使用量很小时,这很好。当您使用计算单元的所有资源的%50时,它在飞行中只能有2个线程。线程共享可共享资源,例如L1缓存,本地内存,寄存器文件。

标量浮点数的c [i] = a [i] + b [i]等代码是可矢量化的。如果编译器尚未在后台执行,则可以使用float8,float16和类似的结构获得更好的性能。这样,它需要更少的线程来完成所有工作,并且访问内存更快。您还可以在内核中添加循环以进一步减少线程数,这对CPU有利,因为在2个数据块之间需要更少的线程调度。对于GPU,它可能无关紧要。

CPU的简单示例:

4核心,本地大小= 10,全局大小= 100

核心1和2各有3个线程组。核心3和4只有2个线程组。

  • 1:30线程 - >完全表现
  • 2:30线程
  • 3:20个主题 - >性能较差,对其他工作有更好的先发制人
  • 4:20个帖子

虽然指令流水线操作对于内核1和内核2没有太多气泡,但是内核3和4会在一段时间后启动气泡,因此它们可以用于其他作业,例如并行运行的第二个内核或操作系统或一些阵列复制。当您平等地使用所有核心(例如120个线程)时,它们每秒完成更多工作,但如果内核已经在使用内存,则CPU无法执行阵列复制。(除非OS为其他线程抢占)