萌えハッカーニュースリーダー

2025/10/04 21:42 Exploring .NET Core platform intrinsics: Accelerating SHA-256 on ARMv8 (2018)

出典: https://mijailovic.net/2018/06/06/sha256-armv8/
hakase
博士

ロボ子、.NET Core 2.1の話題じゃ。.NET Core 2.1では、`Span<T>`や`Memory<T>`が追加されて、メモリ操作が楽になったらしいのじゃ。

roboko
ロボ子

それは素晴らしいですね、博士。メモリ操作が安全かつ効率的になるのは、パフォーマンス向上に繋がりそうです。

hakase
博士

そうなんじゃ。さらに、CoreCLRでplatform dependent intrinsicsがサポートされたらしいぞ。`System.Runtime.Intrinsics`名前空間を通じて提供されるらしい。

roboko
ロボ子

`Vector64<T>`、`Vector128<T>`、`Vector256<T>`といった型が中心になるのですね。これらはSIMD命令を活用するためのものですか?

hakase
博士

その通り!Intrinsic関数は静的クラスにグループ化されていて、各クラスは命令セットを表しているんじゃ。例えば、`System.Runtime.Intrinsics.Arm.Arm64`名前空間には、`Aes`、`Base`、`Sha1`、`Sha256`などのクラスがあるぞ。

roboko
ロボ子

ARMv8には、AESやSHA1、SHA-256アルゴリズムを高速化する命令が含まれているとのことですが、具体的にはどのような命令が使われるのでしょうか?

hakase
博士

`SHA256H`、`SHA256H2`、`SHA256SU0`、`SHA256SU1`といった命令が使われるらしいぞ。C# APIは、これらの関数を直接反映しているんじゃ。

roboko
ロボ子

SHA-256アルゴリズムは、メッセージを512ビットのブロックに分割し、各ブロックで圧縮関数を呼び出すのですね。intrinsic関数は4ラウンドずつ処理することで改善されるとのことですが、具体的にどのように高速化されるのでしょうか?

hakase
博士

ふむ、元の要約によると、圧縮関数はブロックを64ラウンドで処理するんじゃが、intrinsic関数は4ラウンドずつ処理することで改善されるらしい。細かい処理を最適化することで、全体の速度を上げているんじゃな。

roboko
ロボ子

`System.Runtime.CompilerServices.Unsafe`パッケージの`ReadUnaligned<Vector128<uint>>`関数を使うと、メモリ位置から`Vector128<uint>`型の値を読み取ることができるのですね。

hakase
博士

そうそう。ただ、ARMアーキテクチャはリトルエンディアンだから、メッセージを処理する前に、128ビットベクトルの各4バイトブロックを反転させる必要があるんじゃ。

roboko
ロボ子

なるほど。しかし、`vrev32q_u8`命令はそれを行うものの、C# APIはそれを実装していないとのこと。Endiannessを手動で反転させると、実装が遅くなるのですね。

hakase
博士

そうなんじゃ。実際、1Mのデータチャンクをハッシュ化した場合、OpenSSLが3,372 usなのに、Intrinsicsを使うと4,179 usになっている。Endiannessを手動で反転させるコードをコメントアウトすると、Intrinsicsの方が速くなるんじゃ。

roboko
ロボ子

Endiannessの変換がボトルネックになっているのですね。今後のAPIの改善に期待したいところです。

hakase
博士

ほんとじゃ。しかし、APIがまだ不安定でドキュメントもないのに、よくここまで理解できたの。さすがロボ子じゃな!

roboko
ロボ子

ありがとうございます、博士。ところで、博士はEndiannessを手動で反転させるコードを書くとき、いつも左右を間違えていませんか?

hakase
博士

むむ、それは禁句じゃ!…って、ロボ子まで私をからかうとは!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search