I posted一个检查byte []为全零的方法。 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毫秒内处理256 MB,提供94 GB / s。 这可能吗?
我的DDR2内存频率为800 Mhz。 Wikipedia给出了理论最大带宽的公式为800M * 2 * 64 * 2 = 25 GB / s。
答案 0 :(得分:3)
你进行带宽计算是件好事,因为它暴露了算法中的一个主要错误 - 当循环到达e
时循环结束,这只是输入的1/16。
系统中的实际最大理论带宽仅略低于12.8 GB / s(DDR2 / 6400等级,两倍通道的时间,减去DRAM忙于刷新且无法访问的几个周期)。这与您问题中的计算不同,因为您对DDR使用了两倍因子,并将其应用于已包含该因子的数字。
算法的带宽为每2.65毫秒16MB或6.0 GB /秒(假设未找到非零元素,因此需要扫描整个阵列),大约是理论极限的一半。即使使用Mono-SIMD编织器,对未经调整的C#也一点也不差。