简体   繁体   English

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

[英]Using SSE 4.2 crc32 algorithm in c# ? Is it possible?

I have to calculate crc32 on a lot of files, and also huge files (several GB).我必须计算很多文件的 crc32,还有大文件(几 GB)。 I tried several algo found on the web like Damieng or this one , and it works, but it is slow (more than 1 min).我尝试了在 web 上找到的几种算法,比如Damieng这个,它可以工作,但速度很慢(超过 1 分钟)。 I found this benchmark on various crc32 algo and found that sse 4.2 have hardware accelerated crc32 method.我在各种 crc32 算法上找到了这个基准,发现 sse 4.2 有硬件加速 crc32 方法。

I didn't find anywhere c# code sample to use SSE crc32 code.我在任何地方都没有找到使用 SSE crc32 代码的 c# 代码示例。

1 - Is it possible? 1 - 有可能吗?

2 - How can I detect if the current cpu is SSE4.2-enabled? 2 - 如何检测当前 cpu 是否启用了 SSE4.2? (to switch the crc32 method) (切换 crc32 方法)

(please code sample if possible) (如果可能,请提供代码示例)

Nowadays we've been spoiled with the System.Runtime.Intrinsics.X86 namespace available in .NET Core 3.0.现在我们已经被 .NET Core 3.0 中可用的System.Runtime.Intrinsics.X86命名空间宠坏了。 Here's the full implementation of the CRC32-C algorithm using SSE 4.2:这是使用 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;
    }
}

I believe Mono allows access to CPU instructions via the Mono.Simd namespace:我相信 Mono 允许通过 Mono.Simd 命名空间访问 CPU 指令:

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

Stackoverflow related question: Stackoverflow 相关问题:

Using SSE in c# is it possible? 在 c# 中使用 SSE 是否可能?

The Mono code is open source. Mono 代码是开源的。 It looks like you can't just add this to a .NET project to get the benefit though as it appears to need the Mono runtime:看起来您不能只将其添加到 .NET 项目中以获得好处,因为它似乎需要 Mono 运行时:

Calling mono c# code from Microsoft .net? 从微软 .net 调用 mono c# 代码?

That said, it will work, but it will be software emulated.也就是说,它会工作,但它将是软件模拟的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM