【问题标题】:Two consecutive kernels or whole-grid cooperative group synchronization?两个连续内核还是全网协同组同步?
【发布时间】:2019-06-02 15:59:00
【问题描述】:

假设我有两个任务要在 GPU 上运行,第二个任务基本上依赖第一个任务的所有工作。传统上,我基本上必须将这些任务编写为两个单独的内核,并安排第二个在第一个之后的某个时间运行。但是 - 使用 CUDA 9,我现在可以在整个网格上同步,完成第一个任务的工作 - using the cooperative groups feature,然后继续让网格完成第二个任务的工作。

我的问题是:

  • 我们能否就编写两个内核的性能以及何时使用全网格同步提供一个经验法则?
  • 如果是这样,会是什么?
  • 如果不是 - 为什么很难确定在哪些情况下哪个更可取?

【问题讨论】:

    标签: performance cuda gpu-cooperative-groups


    【解决方案1】:

    将此作为 CW 答案,以便其他人随意添加他们的意见和编辑。

    grid-wide sync feature in cooperative groups 要求将线程补充(网格的大小)限制为您正在运行的 GPU 的承载能力。这不是主要的性能限制因素,但它要求您编写可以灵活使用不同网格大小的代码,同时仍能实现最大性能。 grid-stride loops 是这种编码策略的典型组成部分。

    因此,网格范围的同步功能通常需要仔细编码和额外的代码开销(例如使用 occupancy API)才能实现最大性能,尤其是与简单或幼稚的内核相比。

    为了抵消程序员工作效率的可能降低,一些可能的好处是:

    1. 在启动开销占整个运行时间的重要部分的情况下,协作式全网格同步可能会带来显着的好处。除了 2 个独立内核的融合之外,可能会在循环中调用内核的算法(例如 jacobi 迭代/松弛或其他时间步长模拟算法)可能会显着受益,因为启动循环可以有效地“移动到 GPU 上”,用单个内核调用替换内核启动循环。

    2. 在存在大量片上“状态”(例如寄存器内容、共享内存内容)的情况下,需要在网格范围同步之前加载,并在之后使用网格范围的同步,然后协作组可能是一个重大的胜利,节省了内核中遵循网格范围同步的时间,这将用于重新加载状态。例如,这似乎是here 的动机(参见第 4.3 节)。我并不是说他们在使用合作小组(他们不是)。我建议他们有动力寻求网格范围的同步,使用当时可用的临时方法,以消除状态重新加载的成本,以及可能的内核启动开销的成本。

    【讨论】:

    • 一个完整的共享内存值多少“状态”是重要的?较少的?更多?
    猜你喜欢
    • 2020-04-15
    • 2012-01-18
    • 1970-01-01
    • 2015-07-21
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多