我必须计算很多文件的 crc32,还有大文件(几 GB)。我尝试了几种在网上找到的算法,比如Damieng或这个,它可以工作,但速度很慢(超过 1 分钟)。我在各种 crc32 算法上找到了这个基准,发现 sse 4.2 有硬件加速 crc32 方法。
我没有找到任何使用 SSE crc32 代码的 c# 代码示例。
1-有可能吗?
2 - 如何检测当前 cpu 是否启用了 SSE4.2?(切换 crc32 方法)
(如果可能,请提供代码示例)
如今,我们已经被System.Runtime.Intrinsics.X86
.NET Core 3.0 中可用的命名空间宠坏了。这是使用 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 相关问题:
Mono 代码是开源的。看起来您不能只是将其添加到 .NET 项目中以获得好处,因为它似乎需要 Mono 运行时:
从 Microsoft .net 调用 mono c# 代码?
也就是说,它会工作,但它将是软件模拟的。