[過去ログ] Qiita 3 - キータぞ、来たぞ、キータだぞー (1002レス)
前次1-
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
272
(1): デフォルトの名無しさん [sage] 2023/08/10(木) 22:01:59.49 ID:4Znn5xIX(1/3) AAS
Rustでも同じ結果となった (diff -u 形式)
fn hoge(num_list: &mut [i32], delete_num: i32) {
 for num in num_list {
-  if *num == delete_num {
-   *num = 0;
-  }
+  *num *= (*num != delete_num) as i32;
 }
}

アセンブラ出力の方はラベルと使用レジスタ名のズレだけ揃えてdiff
hoge:
  test  rsi, rsi
  je   .LBB1_4
  shl  rsi, 2
  xor  eax, eax
+  xor  ecx, ecx
.LBB1_2:
-  cmp  dword ptr [rdi + rax], edx
-  jne  .LBB1_3
-  mov  dword ptr [rdi + rax], 0
-.LBB1_3:
+  mov  r8d, dword ptr [rdi + rax]
+  cmp  r8d, edx
+  cmove r8d, ecx
+  mov  dword ptr [rdi + rax], r8d
  add  rax, 4
  cmp  rsi, rax
  jne  .LBB1_2
.LBB1_4:
  ret
273
(1): デフォルトの名無しさん [sage] 2023/08/10(木) 22:05:03.94 ID:4Znn5xIX(2/3) AAS
つまりC言語もRustもどちらも同じく
if文の時は普通に条件分岐する
比較値を自己掛け算させるとcmoveを使う

生成コードで掛け算が消えてしまうのはいいね
代わりにやってることは
(1) レジスタの値にメモリから読み込む
(2) 比較
(3) 一致していた時のみレジスタに値0を入れる 【cmove】
(4) レジスタの値をメモリへ書き戻す

条件分岐がない代わりに0にしない時も常に書き込みが発生する
ただし読み込んだ位置への書き込みだから
1サイクルのみでキャッシュページミスのペナルティも無くて済むから問題なしか

一方で元の条件分岐ジャンプするコードと比較して速さはどうなの?
分岐予測ミスやパイプラインの乱れとやらがどれだけ効くのか教えて欲しい
275: デフォルトの名無しさん [sage] 2023/08/10(木) 22:36:14.41 ID:4Znn5xIX(3/3) AAS
訂正してる人はコピペミスか実験かどちらかで二重ループになってしまったのを訂正してるっぽいけどよくわからん

アドバイスできることは
clangの方で-O2だとベクタ展開して比較わかりにくくなってるのを
-Os指定すれば展開がなくなりgccとほぼ同じコードになるよ
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.030s