gpt4 book ai didi

multithreading - 局部和全局大小对程序执行的影响 - OpenCl

转载 作者:行者123 更新时间:2023-12-03 12:59:39 28 4
gpt4 key购买 nike

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

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

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

这是我找到的一些示例代码:
enter image description here

我的另一个问题是:局部大小变化如何影响该代码?
正如我所看到的,它显然正在处理 global_id,没有本地人,所以本地大小更改为大于 1 会影响执行该算法所花费的时间吗?

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

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

先感谢您!

最佳答案

I thought that local work size determine how many threads are gonna be used in the same time in parallel, but am I really correct?



正确,但它是每个计算单元,而不是整个设备。如果计算单元多于本地线程组,则设备未完全使用。当线程组的数量多于计算单元但不是确切的多个时,一些计算单元最后会等待其他计算单元。当两个值相等(或精确倍数)时,“多少次”对于完全占据所有 ALUS 很重要。

例如,一个 8 核 cpu 可以定义 8 个计算单元(使用硬件多线程可能会增加 8 个)。但是价格相近的 GPU 可以有 20 到 64 个计算单元。然后,即使在单个计算单元内,许多线程组也可以“进行中”,这不是显式调整的,而是会根据每个线程和每个计算单元甚至每个 gpu 的资源使用情况而改变。

how local size change influence that code? As i see it is clearly working on global_id's, no local one's so is local size change to bigger one than lets say 1 will influence time spent executing that algorithm?



可向量化/可并行化的内核代码可以具有将线程分布到 ALU、内核的 SIMD 或更宽的 GPU 计算单元的 SIMD 的优势。对于一个 CPU,可以同时发出 8 条标量指令。对于 GPU,它可能高达数千。因此,当您将本地大小减小到 1 时,您将并行线程问题的宽度限制为 1 ALU,这会削弱许多架构的性能。当您使本地大小太大时,每个线程的资源会下降并且性能会受到影响。如果你没有任何想法,如果你给它的参数一个 null,opencl api 可以为你调整本地大小。

And when we would have for loop in that algorithm, is it changing anything then regarding local size influence? Do we need to use local_id's to see any difference when changing local size?



对于旧的和静态调度架构,建议使用等于基本 SIMD 宽度宽度的展开步长进行循环展开。不,本地 id 只是对其计算单元中的线程 id 的查询,因此如果您不需要它,则无需查询。

I tested that on few of my programs, and even when I used only global_id's changing local work size gave me significantly shorter executing times. So how does it work?



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

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

诸如用于标量浮点数的 c[i]=a[i]+b[i] 之类的代码是可矢量化的。如果编译器尚未在后台执行此操作,则可以使用 float8、float16 和类似结构获得更好的性能。这样,它需要更少的线程来完成所有工作,并且访问内存也更快。您还可以在内核中添加一个循环以进一步减少线程数,这对 CPU 有好处,因为在 2 个数据 block 之间需要更少的线程调度。对于 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 无法进行数组复制。(除非操作系统抢占其他线程)

    关于multithreading - 局部和全局大小对程序执行的影响 - OpenCl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41826953/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com