1

古典的な積和演算はa = a + b*cです。しかし、現在、1クロックサイクルで整数に対して次の操作を実行できる命令が存在するかどうか疑問に思っています: ( a と b は符号なし64ビット整数です:unsigned long long int )

a = a*2-1
a = a*2+b

現在、私は使用しています:

a *= 2
--a

最初のものと

a *= 2
a += b

2番目のもの。そして、ASM ではそれぞれが 2 つの命令に変換されていると思います。しかし、代わりに 1 つの ASM 命令を使用する方法はありますか (また、Intel CPU のどの命令セット拡張を使用しますか)?

(私はこの操作を何十億回も行うため、それを検索します)

4

2 に答える 2

7
  1. Intel CPU については、LEA説明書を参照してください。両方のタスクを1つの命令で実行できます(ただし、サイクルについてはわかりません)。(例: LEA EAX, [EAX*2+EBX])。これは実際には乗加算を意味するものではないことに注意してください。そのため、面白い名前 (ロード実効アドレス) になっています。

  2. C および C++ では、気にする必要はありません。コンパイラは最善と思われることを行いますが、おそらくその努力を妨げることができます。私は古き良きものにとどまりa = a*2-1ます。

PS:何かが 2 つの命令として翻訳されていると思われる場合は、アセンブリを調べることほど簡単なことはありませんそうすればわかるでしょう。

于 2012-02-11T17:08:53.003 に答える
1

このような操作を 1 つの命令で実行できるアーキテクチャは多数あります。たとえば、a*2 + bコンパイルすると

  • lea eax, [rsi+rdi*2]x86-64 で
  • add r0, r1, r0, lsl #1アーム上
  • add w0, w1, w0, lsl 1ARM64 で
  • lda16 r0, r1[r0]xcoreで

コンパイラは式を適切に最適化します。a *= 2; a += b多くの場合、可読性を低下させるようなことをする理由はありません

Compiler Explorerでデモを見ることができます。


ただし、この操作を何十億回も行うという理由だけでそれを尋ねると、これは本質的にXY 問題になります。なぜなら、C バージョンを変更することは正しい方法ではなく、命令の数を減らすことはランタイムを減らす方法ではないからです。命令数でパフォーマンスを測定しない

最新の CPU はスーパースカラーであり、一部の命令はマイクロコード化されているため、単一の複雑な命令は、並列で実行できる複数の単純な命令よりも遅くなる場合があります。コンパイラは明らかにこれを認識しており、コンパイル中にレイテンシを考慮に入れます。本当の解決策は、マルチスレッドと SIMD を使用することです

たとえば、Clang は AVX-512 のメイン ループで次の命令を発行します。

vpaddd  zmm0, zmm0, zmm0                            ; a *= 2
vpaddd  zmm1, zmm1, zmm1
vpaddd  zmm2, zmm2, zmm2
vpaddd  zmm3, zmm3, zmm3
vpaddd  zmm0, zmm0, zmmword ptr [rsi + 4*rdx]       ; a += b
vpaddd  zmm1, zmm1, zmmword ptr [rsi + 4*rdx + 64]
vpaddd  zmm2, zmm2, zmmword ptr [rsi + 4*rdx + 128]
vpaddd  zmm3, zmm3, zmmword ptr [rsi + 4*rdx + 192]

これには、ループ展開自動ベクトル化の両方が含まれます。各命令は、一度に16 個の 32 ビット整数を処理できます。もちろん、64 ビットを使用している場合intは、一度に「のみ」8 で動作します。さらに、同じ命令はそれぞれ独立して実行できるため、CPU に十分な実行ポートがあれば、64 個intの命令を並列に追加できます。これが「高速」と呼ばれるものです

GCC は、多くの場合、ループのアンローリングであまり積極的ではなく、vpslldその後に. を使用しvpadddます。しかし、それでもスカラー バージョンよりも高速です。ARM では、neon が使用されていることがわかりますshl v0.4s, v0.4s, 1; add v0.4s, v0.4s, v1.4sコンパイラ エクスプローラのデモ リンクは次のとおりです。

「最適化」よりもはるかに高速なマルチスレッドと組み合わせる

于 2019-04-05T17:26:46.640 に答える