我正在测试 .Net C# System.Numerics.Vector 类用于打包和解包位的功能。
我希望 Vector 按位左移/右移功能,但目前不可用,所以我尝试使用如下算术和逻辑方法模拟移位。这是我看到的:
使用 Vector.Multiply() 和 Vector.BitwiseOr() 打包(模拟的按位 SHIFT LEFT 和 OR)比数组/指针代码稍差*。
*<10% 的吞吐量下降 (MB/秒)。
但是使用 Vector.Divide() 和 Vector.BitwiseAnd() 解包(模拟按位 SHIFT RIGHT 和 AND)比数组/指针代码差得多**。
**吞吐量下降 50%
注意:
Vector 使用单元进行了测试(这也在评论中提出)。
测试基础是在 65536 个整数的块中打包和解包 100Mn 到 1Bn 个整数。我为每个块随机生成了 int[]。
我还测试了按位 (& | >> <<) 以及算术 (+ - * /) 运算,发现成本没有明显差异。甚至除法也没有那么糟糕,整体与乘法仅下降 10%(评论中提出了除法问题)
我将原始测试代码(用于非向量比较)更改为不安全/指针例程,以在打包(多个整数到一个单词)与解包(一个单词到多个整数)方面创建更多类似的测试)。这使非向量代码的整体差异(打包和解包之间)降低到 <5%。(这反驳了我对下面的编译器和优化的评论)
非优化向量:打包速度是解包速度的 2 倍
优化向量:在打包方面产生了 4 倍的改进(相对于未优化的向量),在解包方面得到了 2 倍的改进
未优化的数组/指针:解包比打包快约 5%
优化的数组/指针:对打包产生了 3 倍的改进(相对于未优化的数组指针),对解包产生了 2.5 倍的改进。总体而言,优化的数组/指针打包比优化的数组/指针解包快 <5%。
优化的数组/指针打包比优化的向量包快约 10%
到目前为止的结论:
Vector.Divide() 与普通算术除法相比似乎是一个相对较慢的实现
此外,编译器似乎没有将 Vector.Divide() 代码优化到与 Vector.Multiply() 几乎相同的程度(它支持下面关于优化除法的评论)
数组/指针处理目前在打包数据方面比 Vector 类稍快,在解包方面要快得多
System.Numerics 需要 Vector.ShiftLeft() 和 Vector.ShiftRight() 方法
问题(更新);
- 我的结论大体上是正确的吗?还是有其他方面需要检查/考虑?
更多信息:
int numPages = 8192; // up to >15K
int testSize = 65536;
StopWatch swPack = new StopWatch();
StopWatch swUnpack = new StopWatch();
long byteCount = 0;
for (int p = 0; p < numpages; b++)
{
int[] data = GetRandomIntegers(testSize, 14600, 14800);
swPack.Start();
byte[] compressedBytes = pack(data);
swPack.Stop();
swUnpack.Start();
int[] unpackedInts = unpack(compressedBytes);
swUnpack.Stop();
byteCount += (data.Length*4);
}
Console.WriteLine("Packing Throughput (MB/sec): " + byteCount / 1000 / swPack.ElapsedMilliseconds);
Console.WriteLine("Unpacking Throughput (MB/sec): " + byteCount / 1000 / swUnpacking.ElapsedMilliseconds);