1

在翻阅Nicholas Wilt的 CUDA 手册时,我注意到 1 字节和 2 字节的内存事务显然没有合并。但是,据我了解,Fermi 和 Kepler (SM2+) 架构获取了满足内存所需的高速缓存行数。对我来说,这听起来像是合并。

为了节省空间,我的应用程序大量使用了 1 字节和 2 字节数据字段(在大型 2D 间距线性数组中)并锤击全局内存。

我继续对我的应用程序进行了更改,通过简单地将一个无符号整数与四个无符号字符联合并获取联合,让一个线程一次获取 4 个条目。

在我的一些测试数据上运行它,我看到 Kepler 笔记本电脑卡(750M,SM3.5)和 Tesla C2075(SM2.0)的改进了 ~32% 和 ~45%

这种改进的更可能原因是什么?增加了每个线程的工作,减少了整体内存获取请求,或者我对合并如何处理小数据类型的理解不正确?

4

1 回答 1

2

您对费米和开普勒上的聚结的理解或多或少是正确的。它们获取满足 warp 中所有加载请求所需的缓存行数。

首先,鉴于您的加速数字,我得出结论,您的测试受带宽限制。

如果 warp 中的线程正在加载连续字节,则每个 warp 需要 32 个字节。高速缓存行大小为 128 字节,这意味着每个 warp 仅使用其可以获得的带宽的 25%。但这也意味着每个 warp 的负载应该被其他 3 个 warp 重用,假设它们没有首先从缓存中逐出。但这既不存在也不存在,因为如果您有足够的线程,并且负载完全合并,即使没有缓存,您也可能隐藏大部分延迟。

相反,通过每个线程获取 4 个字节,您可以获得较低的缓存重用,但您会利用更多的可用带宽,这可能是您看到加速的原因。

由于您的测试受带宽限制,因此您可以通过为每个线程(8 或 16 字节)加载 uint2 或 uint4 来获得更快的速度。原因是通常你需要一个以上的高速缓存线请求,以使内存带宽完全饱和。所以我也想试试。

于 2013-07-03T01:04:23.553 回答