首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用C# System..Numerics.Vector<T>解压缩/打包位

使用C# System..Numerics.Vector<T>解压缩/打包位
EN

Stack Overflow用户
提问于 2018-05-19 10:31:09
回答 1查看 959关注 0票数 2

我正在测试.Net C# System.Numerics.Vector类打包和解压缩位的功能。

我希望向量向左/向右移位,但这是目前不可用的,所以我尝试使用算术和逻辑方法来模拟移位,如下所示。我看到的是:

使用Vector.Multiply()和Vector.BitwiseOr()打包(模拟的位左移位和OR)比数组/指针代码稍差。

*<10%吞吐量下降(MB/秒)。

但是,使用Vector.Divide()和Vector.BitwiseAnd()解压缩(一个模拟的位右移位和和)要比数组/指针代码糟糕得多。

**吞吐量下降50%

注:

  • 使用单元测试了向量(这也是在注释中提出的)。
  • 试验依据是65536个整数块的1亿至10亿个整数的包装和解压。我为每个块随机生成了int[]。
  • 我还测试了按位运算(&ν>> <<)和算术运算(+ -* /),发现成本没有明显的差别。甚至除法也不是那么糟糕,在整个vs乘法中只有10%的退化(在评论中提出了除法的问题)。
  • 我将最初的测试代码(用于非向量比较)更改为不安全/指针例程,以便在打包(许多整数到一个单词)和解压(一个单词对多个整数)方面创建类似的测试。这使得非矢量码的整个(包装和解压)的差异降到了<5%。(它反驳了我对下面编译器和优化的评论)
  • 非优化向量:包装速度是解压速度的2倍。
  • 优化向量:在包装方面得到了4倍的改进(相对于非优化的向量),而解压的改进是2倍。
  • 非优化数组/指针:解压缩比打包快5%
  • 优化的数组/指针:为打包提供了3倍的改进(相对于非优化的数组指针),而对于解打包则得到了2.5倍的改进。总的来说,优化的数组/指针填充比优化的数组/指针解压缩快5%。
  • 优化的数组/指针填充比优化的向量包快10%

迄今为止的结论:

  • Vector.Divide()似乎是一个相对较慢的实现,而不是普通的算术划分。
  • 此外,编译器似乎没有将Vector.Divide()代码优化到与Vector.Multiply()几乎相同的程度(它支持下面关于部门优化的注释)
  • 数组/指针处理目前在打包数据方面略快于Vector,而对于解打包则要快得多。
  • System.Numerics需要Vector.ShiftLeft() & Vector.ShiftRight()方法

问题(更新);

  • 我的结论是不是已经走上正轨了?还是有其他方面需要检查/考虑?

进一步资料:

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

发布于 2019-06-15 04:15:08

IL

代码语言:javascript
复制
/// non-SIMD fallback implementation for 128-bit right-shift (unsigned)
/// n: number of bit positions to right-shift a 16-byte memory image.
/// Vector(T) argument 'v' is passed by-ref and modified in-situ.
/// Layout order of the two 64-bit quads is little-endian.

.method public static void SHR(Vector_T<uint64>& v, int32 n) aggressiveinlining
{
    ldarg v
    dup
    dup
    ldc.i4.8
    add
    ldind.i8
    ldc.i4.s 64
    ldarg n
    sub
    shl

    ldarg v
    ldind.i8
    ldarg n
    shr.un

    or
    stind.i8

    ldc.i4.8
    add
    dup
    ldind.i8
    ldarg n
    shr.un
    stind.i8

    ret
}

伪码

代码语言:javascript
复制
As<Vector<ulong>,ulong>(ref v) = (As<Vector<ulong>,ulong>(in v) >> n) | 
                                  (ByteOffsAs<Vector<ulong>,ulong>(in v, 8) << (64 - n));
ByteOffsAs<Vector<ulong>,ulong>(ref v, 8) >>= n;

C# extern声明

代码语言:javascript
复制
static class vector_ext
{
    [MethodImpl(MethodImplOptions.ForwardRef | MethodImplOptions.AggressiveInlining)]
    extern public static void SHR(ref Vector<ulong> v, int n);
};

您可以使用< code >D18中的“链接时间代码生成”选项将由IL (ildasm.exe)和C# (csc.exe)生成的中间二进制文件链接到单个程序集中。

运行时x64 JIT结果(.NET Framework4.7.2)

代码语言:javascript
复制
0x7FF878F5C7E0    48 89 4C 24 08       mov qword ptr [rsp+8],rcx
0x7FF878F5C7E5    8B C2                mov eax,edx
0x7FF878F5C7E7    F7 D8                neg eax
0x7FF878F5C7E9    8D 48 40             lea ecx,[rax+40h]
0x7FF878F5C7EC    48 8B 44 24 08       mov rax,qword ptr [rsp+8]
0x7FF878F5C7F1    4C 8B 40 08          mov r8,qword ptr [rax+8]
0x7FF878F5C7F5    49 D3 E0             shl r8,cl
0x7FF878F5C7F8    4C 8B 08             mov r9,qword ptr [rax]
0x7FF878F5C7FB    8B CA                mov ecx,edx
0x7FF878F5C7FD    49 D3 E9             shr r9,cl
0x7FF878F5C800    4D 0B C1             or  r8,r9
0x7FF878F5C803    4C 89 00             mov qword ptr [rax],r8
0x7FF878F5C806    48 83 C0 08          add rax,8
0x7FF878F5C80A    8B CA                mov ecx,edx
0x7FF878F5C80C    48 D3 28             shr qword ptr [rax],cl
0x7FF878F5C80F    C3                   ret
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50424289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档