1

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

对于较小的瓷砖尺寸,我接近于天真的速度,这是预期的。对于任何大于 16 的图块大小(我会选择 2 的幂,因为我的矩阵大小也是如此),例如 32,内核会引发 sycl 异常。

我怀疑这是因为 GPU 无法在其本地缓存上容纳更高的切片大小。

问题:

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

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

PS:如果想看我的内核代码,请加评论,我会加的。我目前不觉得有必要展示内核代码和臃肿的帖子。

4

2 回答 2

3

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

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

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

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

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

于 2020-10-22T09:21:37.680 回答
0

@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)。如果有人想进一步看,这也在这里得到证实。
于 2020-10-23T11:20:31.580 回答