CUDA-计算内存事务的次数
使用float4需要几次128位内存事务;而加载4个double需要几次128位事务
在 NVIDIA GPU 中,内存事务的大小通常是 128B(128 字节),而数据类型的大小会影响 内存事务的次数。我们来分析 float4
和 double4
的内存事务情况。
1. 使用 float4
需要多少次 128B 内存事务?
(1) float4
结构
struct float4 {
float x, y, z, w; // 每个 float 占 4 字节
};
- 单个
float4
变量占 16 字节(4×4B)。 - 一个 warp 有 32 个线程,如果每个线程加载一个
float4
:- 需要加载
32 × 16B = 512B
。
- 需要加载
(2) 计算内存事务
- 128B 内存事务一次最多传输 32 个 float(即
float
类型的 4B × 32 = 128B)。 - 加载 512B 数据,需要
512B ÷ 128B = 4 次 128B 内存事务
。
✅ 结论:使用 float4
进行 warp 级别的合并访问需要 4 次 128B 内存事务。
2. 使用 double4
需要多少次 128B 内存事务?
(1) double4
结构
struct double4 {
double x, y, z, w; // 每个 double 占 8 字节
};
- 单个
double4
变量占 32 字节(4×8B)。 - 一个 warp 有 32 个线程,如果每个线程加载一个
double4
:- 需要加载
32 × 32B = 1024B
。
- 需要加载
(2) 计算内存事务
- 128B 内存事务一次最多传输 16 个 double(即
double
类型的 8B × 16 = 128B)。 - 加载 1024B 数据,需要
1024B ÷ 128B = 8 次 128B 内存事务
。
✅ 结论:使用 double4
进行 warp 级别的合并访问需要 8 次 128B 内存事务。
3. 总结
数据类型 | 单个线程加载大小 | 32 线程总大小 | 每次事务加载大小 | 需要的事务数 |
---|---|---|---|---|
float4 | 16B | 512B | 128B | 4 |
double4 | 32B | 1024B | 128B | 8 |
🔹 float4
需要 4 次 128B 内存事务,而 double4
需要 8 次 128B 内存事务。
🔹 double
由于大小为 8B,导致相同 warp 访问需要更多事务,吞吐量降低。
🔹 使用 float4
更有利于高效合并访问,而 double4
可能导致更多内存事务,影响性能。
🚀 优化建议:如果可能,尽量使用 float4
进行向量化访问,减少内存事务,提高 GPU 带宽利用率!