在c#中使用SSE 4.2 crc32算法?这可能吗?

本文关键字:算法 crc32 SSE | 更新日期: 2023-09-27 18:05:08

我必须在很多文件上计算crc32,而且是巨大的文件(几个GB)。我尝试了几个算法在网上找到像Damieng或这个,它的工作,但它很慢(超过1分钟)。我在各种crc32算法上找到了这个基准测试,发现sse 4.2有硬件加速的crc32方法。

我没有找到任何c#代码样本来使用SSE crc32代码。

1 -有可能吗?

2 -如何检测当前cpu是否使能sse4.2 ?(切换crc32方法)

(可能的话请提供代码示例)

在c#中使用SSE 4.2 crc32算法?这可能吗?

现在我们已经被。net Core 3.0中可用的System.Runtime.Intrinsics.X86命名空间宠坏了。下面是使用SSE 4.2的CRC32-C算法的完整实现:

using System;
using System.Runtime.Intrinsics.X86;
using System.Security.Cryptography;
/// <summary>
/// The hardware implementation of the CRC32-C polynomial 
/// implemented on Intel CPUs supporting SSE4.2.
/// </summary>
public class Crc32HardwareAlgorithm : HashAlgorithm
{
    /// <summary>
    /// the current CRC value, bit-flipped
    /// </summary>
    private uint _crc;
    /// <summary>
    /// We can further optimize the algorithm when X64 is available.
    /// </summary>
    private bool _x64Available;
    /// <summary>
    /// Default constructor
    /// </summary>
    public Crc32HardwareAlgorithm()
    {
        if (!Sse42.IsSupported)
        {
            throw new NotSupportedException("SSE4.2 is not supported");
        }
        _x64Available = Sse42.X64.IsSupported;
        // The size, in bits, of the computed hash code.
        this.HashSizeValue = 32;
        this.Reset();
    }
    /// <summary>When overridden in a derived class, routes data written to the object into the hash algorithm for computing the hash.</summary>
    /// <param name="array">The input to compute the hash code for.</param>
    /// <param name="ibStart">The offset into the byte array from which to begin using data.</param>
    /// <param name="cbSize">The number of bytes in the byte array to use as data.</param>
    protected override void HashCore(byte[] array, int ibStart, int cbSize)
    {
        if (_x64Available)
        {
            while (cbSize >= 8)
            {
                _crc = (uint)Sse42.X64.Crc32(_crc, BitConverter.ToUInt64(array, ibStart));
                ibStart += 8;
                cbSize -= 8;
            }
        }
        while (cbSize > 0)
        {
            _crc = Sse42.Crc32(_crc, array[ibStart]);
            ibStart++;
            cbSize--;
        }
    }
    /// <summary>When overridden in a derived class, finalizes the hash computation after the last data is processed by the cryptographic stream object.</summary>
    /// <returns>The computed hash code.</returns>
    protected override byte[] HashFinal()
    {
        uint outputCrcValue = ~_crc;
        return BitConverter.GetBytes(outputCrcValue);
    }
    /// <summary>Initializes an implementation of the <see cref="T:System.Security.Cryptography.HashAlgorithm"></see> class.</summary>
    public override void Initialize()
    {
        this.Reset();
    }
    private void Reset()
    {
        _crc = uint.MaxValue;
    }
}

我相信Mono允许通过Mono访问CPU指令。Simd名称空间:

http://tirania.org/blog/archive/2008/nov - 03. - html

与Stackoverflow相关的问题: 在c#中使用SSE是可能的吗?

Mono代码是开源的。看起来你不能仅仅把它添加到。net项目中来获得好处,因为它似乎需要Mono运行时:

从microsoft.net调用mono c#代码?

也就是说,它会工作,但它将是软件模拟。