SSE指令无视RAM理论带宽
本文关键字:理论 带宽 RAM 指令 SSE | 更新日期: 2023-09-27 18:18:59
我发布了一个方法检查字节[]为全零。Mono。Simd提供了如此高的性能,我想知道这是否可能。
static unsafe bool IsAllZeros(byte[] data)
{
fixed (byte* bytes = data) {
int len = data.Length;
int rem = len % (16*16);
Vector16b* b = (Vector16b*)bytes;
Vector16b* e = b + len / (16*16);
Vector16b zero = Vector16b.Zero;
while (b < e) {
if ((*(b)|*(b+1)|*(b+2)|*(b+3)|*(b+4)|*(b+5)|*(b+6)|*(b+7)|*(b+8)|
*(b+9)|*(b+10)|*(b+11)|*(b+12)|*(b+13)|*(b+14)|*(b+15)) != zero)
return false;
b += 16;
}
for (int i = 0; i < rem; i++)
if (data [len - 1 - i] != 0)
return false;
return true;
}
}
上面的代码在2,6477 ms内处理256 MB,给出94 GB/s。这可能吗?
我的DDR2内存有800mhz的频率。维基百科给出的理论最大带宽公式为800M*2*64*2 = 25gb/s
你做了带宽计算,这很好,因为它暴露了你的算法中的一个主要错误——当它到达e
时循环结束,这只是输入路径的1/16。
系统的实际最大理论带宽仅略低于12.8 GB/s (DDR2/6400额定值,乘以两个通道,减去DRAM忙于刷新而无法访问的几个周期)。这与您问题中的计算不同,因为您对DDR使用了因子2,并将其应用于已经包含该因子的数字。
你的算法的带宽是16MB/2.65 ms或6.0 GB/s(假设没有发现非零元素,因此需要扫描整个数组),大约是理论限制的一半。对于未调优的c#来说,这一点都不错,即使使用了Mono-SIMD编织器。