このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
Fixstars では暗号アルゴリズムの高速化を行っています。暗号アルゴリズムでは、素体 \(\mathbb{F}_p\) を扱うものが多くあり、その際、\(\mathbb{F}_p\) の上での乗算を実装する必要があります。
この乗算は非負整数の剰余付き乗算 \(z := x \cdot y \pmod p\) となります。素直にこの式に従って計算すると、 \(p\) で割った余りを求めるために除算・剰余算が使用されます。しかし除算・剰余算は、少なくとも現在普及しているアーキテクチャでは効率的ではないため、実装の際は整数除算を実行せずに済むモンゴメリ乗算が採用されます。
本記事では、モンゴメリ乗算のプログラムを 3 種類用意し、パフォーマンス分析を行い、モンゴメリ乗算の SIMD 化の効果を確かめます。
AVX-512 命令セットの基本的なサブセット(AVX-512F + AVX-512VL)の組み込み関数を用いた実装
更に AVX-512IFMA52 命令セットの組み込み関数を用いた実装
プログラム 1 および 2 で実装したアルゴリズムは参考文献 [BMSZ2013] のものとなります。
AVX-512 命令セットを搭載したマイクロアーキテクチャは、Knights Landing や Skylake-SP 以降、サーバーやハイエンドデスクトップ向けの CPU に含まれることが多く、ラップトップ向け CPU に関しては Ice Lake 以降となります。とはいえ 2024 年現在、気が付けば手元のラップトップの Intel CPU が Ice Lake 以降のマイクロアーキテクチャだった、ということは珍しくなく、手元でも手軽に AVX-512 命令セット(のサブセット)が使用できる時代になりました。AVX-512 ではマスクレジスタの導入に伴うマスク命令によって、AVX2 よりもかなり SIMD プログラミングがしやすくなったと実感する場面が多いかと思います。
AVX-512 命令セットの新たなサブセットとして AVX-512IFMA52 が Ice Lake マイクロアーキテクチャで実装されました。IFMA は Integer Fused Multiply-Add の略です。Intel のドキュメント等で記載が見られているわけではないですが、倍精度浮動小数点数の仮数部が 52-bit であり、IFMA52 はその回路を利用していると考えられ、参考文献 [GK2016] にもその記述があります。
IFMA52 が使用できない場合、整数乗算の命令は、最長でも vpmuludq
命令によって(32 bit 整数)*(32 bit 整数)=(64 bit 整数)までしか扱えません。一方で IFMA52 を使用できる場合、vpmadd52{h,l}uq
命令によって(52 bit 整数)*(52 bit 整数)=(104 bit 整数)を簡単に扱うことができるようになります。
暗号では数百 ~ 数千ビット長の整数を扱います。すなわち多倍長整数として表現する必要があります。
1、AVX-512 命令セットの基本的なサブセット(AVX-512F + AVX-512VL)を用いた実装では、整数を 32-bit ずつに分割します。 例えば 150 ビット長の整数を扱う場合、メモリ上の整数の(AoSoA 的な)データ配置は下図のようになります。256-bit ベクトルレジスタを用いた場合、SIMD によって同時に 8 個の整数に対して演算が行われ、8 個の整数はそれぞれ 5 分割されることになります。
2、更に AVX-512IFMA52 命令セットを用いた実装では、整数を 52-bit ずつに分割します。ただしメモリ上は 64-bit に分割する必要があるため、上位 12-bit 分は 0 をパディングします。例えば 150 ビット長の整数を扱う場合、メモリ上の整数の(AoSoA 的な)データ配置は下図のようになります。256-bit ベクトルレジスタを用いた場合、SIMD によって同時に 4 個の整数に対して演算が行われ、4 個の整数はそれぞれ 3 分割されることになります。
モンゴメリ乗算のアルゴリズムは、この分割数の 2 乗に概ね比例する命令数を要するため、分割数を減らすことで性能向上が期待できます。具体的には、整数を 32-bit ではなく 52-bit ずつに分割することで、アルゴリズムの計算量と各種 SIMD 命令のスループットを考慮すると、モンゴメリ乗算の効率を 85 % 程度高めることができることが見積もれます。
それぞれのモンゴメリ乗算のプログラムをビルドしてパフォーマンスを計測した結果を下図の両対数プロットに記します。AVX-512IFMA52 命令セットを用いた実装では、確かにモンゴメリ乗算が高速となったことが確かめられます。
プロットの見方:
補足:
課題:
今回のモンゴメリ乗算の実装では、元々、主に 100 ビット前後の多倍長整数に焦点を当てたものでした。その範囲で SIMD 実装の Clang ビルドは Number Theoretic Library よりも大幅に高速化され、AVX-512IFMA52 を用いた SIMD 実装が AVX-512IFMA52 を用いない SIMD 実装より、理論値通り約 85% 高速となったことが確かめられました。
また、理論値と実測値の差異に関しても突き詰め、その理由を考察して十分に説明可能なものとなりました。
本記事を完成させるにあたり、インターン生の宮下敦行様からの実装と分析に関する貢献がありましたことを、感謝申し上げます。
keisuke.kimura in Livox Mid-360をROS1/ROS2で動かしてみた
Sorry for the delay in replying. I have done SLAM (FAST_LIO) with Livox MID360, but for various reasons I have not be...
Miya in ウエハースケールエンジン向けSimulated Annealingを複数タイルによる並列化で実装しました
作成されたプロファイラがとても良さそうです :) ぜひ詳細を書いていただきたいです!...
Deivaprakash in Livox Mid-360をROS1/ROS2で動かしてみた
Hey guys myself deiva from India currently i am working in this Livox MID360 and eager to knwo whether you have done the...
岩崎システム設計 岩崎 満 in Alveo U50で10G Ethernetを試してみる
仕事の都合で、検索を行い、御社サイトにたどりつきました。 内容は大変参考になりま...
Prabuddhi Wariyapperuma in Livox Mid-360をROS1/ROS2で動かしてみた
This issue was sorted....