簡體   English   中英

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

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

我必須計算很多文件的 crc32,還有大文件(幾 GB)。 我嘗試了在 web 上找到的幾種算法,比如Damieng這個,它可以工作,但速度很慢(超過 1 分鍾)。 我在各種 crc32 算法上找到了這個基准,發現 sse 4.2 有硬件加速 crc32 方法。

我在任何地方都沒有找到使用 SSE crc32 代碼的 c# 代碼示例。

1 - 有可能嗎?

2 - 如何檢測當前 cpu 是否啟用了 SSE4.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.Simd 命名空間訪問 CPU 指令:

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

Stackoverflow 相關問題:

在 c# 中使用 SSE 是否可能?

Mono 代碼是開源的。 看起來您不能只將其添加到 .NET 項目中以獲得好處,因為它似乎需要 Mono 運行時:

從微軟 .net 調用 mono c# 代碼?

也就是說,它會工作,但它將是軟件模擬的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM