估算 GPU 矩阵计算的最佳分块大小

Estimating the optimal tiling size for GPU matrix computations

我基于将子矩阵平铺到本地缓存,在 SYCL 中编写了一个矩阵乘法内核。我使用平铺(平铺大小 16x16)和不使用平铺(原始)方法获得的性能提升高达 2 倍。

对于较小的图块尺寸,我接近原始速度,这是预期的。对于任何大于 16 的图块大小(我会选择 2 的幂,因为我的矩阵大小也是如此),例如 32,内核会抛出一个 sycl 异常。

我怀疑这是因为 GPU 无法在其本地缓存中容纳更大的图块大小。

问题:

  1. 如何动态确定(并设置)在不同 GPU 上部署时支持的最大图块大小?
  2. 对于 Intel GPU,如何找出最大 GPU 本地缓存大小?

我尝试检查 ark.intel.com,但未列出 GPU 本地缓存大小。 当前设置:带有 Intel UHD 620 的 i7-8665U

P.S:如果你想看我的内核代码,请加评论,我会加的。我目前觉得没有必要显示内核代码和膨胀 post.

一般来说,在矩阵乘法平铺中,您需要注意以下几点:

  1. 每个线程的图块大小 - 因为您需要将数据保存在令人恐惧的寄存器中,例如对于 NVidia,它大约为 256 - 所以您不能自动制作大于 16x16 的图块 - 实际上是 6x6/ 8x8 是每个线程 nvidia/amd/intel gpus
  2. 的最佳选择
  3. 最好将大图块(如 128x128 或 72x72(对于 AMD))加载到本地内存并将工作负载分配到工作组中每个线程的较小图块上 - 但您应该非常小心避免银行冲突
  4. 最佳参数 selection 取决于 gpu 供应商(amd/nvidia/intel/arm-mali 等)、gpu version/generation,当然还有矩阵大小。例如,CLBlast 有用于矩阵乘法参数的复杂调整例程 selection.

因此,为了 select 最佳参数,您需要查看 wavefront/wrap/simd 大小 amd/nvidia/intel gpu(64 或 32/32/8-32)本地内存条的数量,每个线程的寄存器计数等。一般来说,可以使用自动调整和缓存这些值来完成。

我发现本教程对于理解进行快速矩阵乘法的各种问题非常有帮助:

https://cnugteren.github.io/tutorial/pages/page1.html

即使在那里,他也获得了大约 50-60% 的效率。实现好的矩阵乘法算法很难。

这是英特尔特定教程:https://software.intel.com/content/www/us/en/develop/articles/sgemm-for-intel-processor-graphics.html

@Artyom 解释了在 GPU 上实现矩阵乘法时需要注意的事项。

关于问题,以下是 SYCL 中显示我正在寻找的内容的片段:

// Create a queue with device
default_selector d_selector;
queue q(d_selector, dpc_common::exception_handler);
std::cout << "Enumerated Device: " 
          << q.get_device().get_info<info::device::name>() << "\n";
auto wgroup_size = q.get_device().get_info<info::device::max_work_group_size>();
auto local_mem_size = q.get_device().get_info<info::device::local_mem_size>();
auto global_mem_size = q.get_device().get_info<info::device::global_mem_size>();

std::cout << "Maximum workgroup size\t:" << wgroup_size << "\n" 
        << "Global Memory Size\t:" << global_mem_size / 1024 / 1024 << " MB\n"
        << "Local Memory Size\t:" << local_mem_size / 1024 << " KB\n";

这表明:

Enumerated Device: Intel(R) Gen9
Maximum workgroup size  :256
Global Memory Size      :3199 MB
Local Memory Size       :64 KB
  1. 最大工作组大小为 256,即在每个维度上,最多支持 16 个。
  2. 本地缓存大小为 65536 字节 (64KB)。如果有人想进一步看的话,这也得到了证实here