7

我正在设计一组数学函数并在 CPU 和 GPU(使用 CUDA)版本中实现它们。

其中一些函数基于查找表。大多数表占用 4KB,其中一些需要更多。基于查找表的函数接受一个输入,选择查找表的一个或两个条目,然后通过插值或应用类似技术来计算结果。

我现在的问题是:我应该在哪里保存这些查找表?CUDA 设备有许多存储值的地方(全局内存、常量内存、纹理内存……)。假设每个表可以被多个线程同时读取,并且输入值以及查找索引在每个 warp 的线程之间可以完全不相关(导致不相关的内存访问),那么哪个内存提供最快的访问?

我补充说,这些表的内容是预先计算的并且完全不变。

编辑

澄清一下:我需要存储大约 10 个不同的 4KB 查找表。无论如何,很高兴知道对于这种情况的解决方案是否与例如 100 个 4KB 表或例如 10 个 16KB 查找表的情况相同。

4

1 回答 1

2

纹理内存(现在称为只读数据缓存)可能是一个值得探索的选择,尽管不是为了插值优势。它支持 32 位读取,而不会超出此数量。但是,您总共限制为 48K。对于 Kepler(计算 3.x)来说,现在编程非常简单。

全局内存,除非您将其配置为 32 位模式,否则通常会为每个线程拖入 128 个字节,大大增加了内存中实际需要的数据,因为您(显然)无法合并内存访问。因此,如果您想使用超过 48K(您提到 40K),则可能需要 32 位模式。

考虑合并,如果您要从这些表中依次访问一组值,您可能能够交错这些表,以便这些组合可以分组并作为每个线程读取的 64 位或 128 位读取。这意味着从全局内存读取 128 字节可能很有用。

您将遇到的问题是您正在通过使用查找表来限制解决方案的内存带宽。将 L1 缓存大小(在 Fermi / 计算 2.x 上)更改为 48K 可能会产生重大影响,尤其是在您不使用其他 32K 共享内存的情况下。尝试纹理内存,然后在 32 位模式下尝试全局内存,看看哪个最适合您的算法。如果您可以选择硬件,请最后选择具有良好内存带宽的卡。

于 2013-07-16T15:07:04.463 回答