【问题标题】:OpenCL: Confused by CL_DEVICE_MAX_COMPUTE_UNITSOpenCL:被 CL_DEVICE_MAX_COMPUTE_UNITS 弄糊涂了
【发布时间】:2017-05-13 01:57:45
【问题描述】:

我对这个 CL_DEVICE_MAX_COMPUTE_UNITS 感到困惑。例如我在 Mac 上的 Intel GPU,这个数字是 48。这是否意味着同时运行的最大并行任务数是 48 或 48 的倍数,可能是 96、144...? (我知道每个计算单元由 1 个或多个处理元素组成,每个处理元素实际上负责一个“线程”。如果 48 个计算单元中的每一个都由多个处理元素组成怎么办)。换句话说,对于我的 Mac 来说,“理想”加速虽然在现实中是不可能的,但比 CPU 内核快 48 倍(我们假设 CPU 和 GPU 的单个“内核”计算速度相同),或者是48,也许是 96、144……?

【问题讨论】:

  • 这很复杂。术语“计算单元”没有严格定义。尽管如此,也许有人可以给出一个“好”的答案,但我想指出一个相关问题:stackoverflow.com/questions/9326430/…(还有其他几个相关问题 - 不确定其中一个是否与此重复)

标签: opencl


【解决方案1】:

总结:您的加速有点复杂,但是您的机器(英特尔 GPU,可能是 GEN8 或 GEN9)的 fp32 吞吐量 768 每个 (GPU) 时钟的 FLOP 和 fp16 的 1536。让我们假设 fp32,所以小于 768x(可能是其中的三分之一,取决于 CPU 速度)。有关推理和一些非常重要的注意事项,请参见下文。

关于 CL_DEVICE_MAX_COMPUTE_UNITS 的简短说明: 英特尔在其 GPU 驱动程序中使用 CL_DEVICE_MAX_COMPUTE_UNITS 时会做一些奇怪的事情。

来自clGetDeviceInfo (OpenCL 2.0)。 CL_DEVICE_MAX_COMPUTE_UNITS 说

OpenCL 设备上的并行计算单元数。一种 工作组在单个计算单元上执行。最小值为 1。

但是,英特尔显卡驱动程序实际上并未遵循此定义,而是返回 EU(执行单元)的数量 --- 一个 EU,一组 SIMD ALU 和插槽用于 7 个不同的 SIMD 线程(寄存器等) .每个 SIMD 线程代表 8、16 或 32 个工作项,具体取决于编译器选择的内容(我们想要更高,但寄存器压力会迫使我们降低)。

一个工作组实际上仅限于一个“切片”(see the figure in section 5.5 "Slice Architecture"),恰好是 24 个 EU(在最近的硬件中)。选择 GEN8 或 GEN9 文档。每个切片都有自己的 SLM、障碍和 L3。鉴于您的 Apple Book 报告了 48 个 EU,我会说您有两个部分。

最大加速: 让我们忽略这个主要的烦恼并使用欧盟编号(以及上面的那些拱文档)。对于“加速”,我正在比较 CPU 上的单线程 FP32 计算。如果 CPU 具有良好的并行化等,当然加速会更少。

在理想情况下,48 个 EU 中的每一个都可以在每个时钟发出两个 SIMD4 操作。假设这些是融合的乘加(实际上是两个操作),这给了我们:

48 EUs * 2 SIMD4 ops per EU * 2 (if the op is a fused multiply add) 
= 192 SIMD4 ops per clock
= 768 FLOPs per clock for single precision floating point

所以你理想的加速实际上是 ~768。但是有很多东西可以计算出这个理想的数字。

  1. 设置和拆卸时间。让我们忽略这一点(假设 WL 时间支配运行时)。
  2. GPU 时钟最高可达千兆赫,而 CPU 运行速度更快。将该比率考虑在内。(大概是 1/3?CPU 上 3Ghz 与 GPU 上 1Ghz)。
  3. 如果计算不是大量乘加“疯狂”,则除以 2,因为我在上面加倍。但是,许多重要的工作负载都是“疯狂”的。
  4. 执行大部分是非发散的。如果 SIMD 线程分支为 if-then-else,则整个 SIMD 线程(8、16 或 32 个工作项)都必须执行该代码。
  5. 注册银行冲突延迟会降低 EU ALU 吞吐量。通常,编译器会很好地避免这种情况,但理论上它会稍微影响您的性能(通常取决于寄存器压力的几个百分点)。
  6. 缓冲区地址计算也可以减少几个百分点(EU 必须花时间进行整数计算以读取和写入地址)。
  7. 如果使用过多的 SLM 或障碍,GPU 必须让一些 EU 空闲,以便机器上的每个工作项都有足够的 SLM。 (您可以调整算法来解决此问题。)
  8. 我们必须保持 WL 计算绑定。如果我们炸毁数据访问层次结构中的任何缓存,我们就会遇到没有线程准备好在 EU 上运行并且必须停止的情况。假设我们避免这种情况。 ?.我可能忘记了其他可能出错的事情。

我们称​​效率为理论完美的百分比。因此,如果我们的工作负载以每时钟约 530 FLOPs 运行,那么我们的效率是理论 768 的 60%。我已经看到非常仔细调整的工作负载效率超过 90%,但它肯定需要一些工作。

【讨论】:

    【解决方案2】:

    您可以获得的理想加速是处理元素的总数,在您的情况下对应于 48 * 每个计算单元的处理元素数。我不知道如何从 OpenCL 中获取处理元素的数量(这并不意味着它不可能),但是您可以在 Google 上搜索您的 GPU。

    据我所知,一个计算单元由一个或多个处理元素(GPU 通常很多)、一个寄存器文件和一些本地内存组成。计算单元的线程以 SIMD(单指令多数据)方式执行。这意味着计算单元的线程都执行相同的操作,但对不同的数据。

    此外,您获得的加速取决于您执行内核函数的方式。由于单个工作组不能在多个计算单元上运行,因此您需要足够数量的工作组才能充分利用所有计算单元。此外,工作组大小应该是 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 的倍数。

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 2019-01-12
      • 1970-01-01
      • 2014-08-14
      • 2016-02-16
      • 1970-01-01
      • 2017-07-24
      • 2011-08-02
      • 1970-01-01
      相关资源
      最近更新 更多