10時起床.前日比±0
配列の中身をコピーする方法をいくつか試したら,実行時間が若干変わったのが気になった.
Mad521の修正 · ykm11/lab-youth@a41fa77 · GitHub
for文を使ってのコピーは賢くないな.
次のようなコードを書いてみる.実行環境はUbuntu, gcc 9.3.0
void f(mp_limb_t *a, const mp_limb_t *b) {
memcpy(a, b, sizeof(mp_limb_t) * 9);
}
void g(mp_limb_t *a, const mp_limb_t *b) {
memcpy(a, b, sizeof(mp_limb_t) * 8);
a[8] = b[8];
}
-O3でコンパイルすると同じアセンブリが出てくる(のでどちらが良い, 速いとかはない).
movdqu xmm0,XMMWORD PTR [rsi]
movdqu xmm0,XMMWORD PTR [rsi]
movups XMMWORD PTR [rdi],xmm0
movdqu xmm1,XMMWORD PTR [rsi+0x10]
movups XMMWORD PTR [rdi+0x10],xmm1
movdqu xmm2,XMMWORD PTR [rsi+0x20]
movups XMMWORD PTR [rdi+0x20],xmm2
movdqu xmm3,XMMWORD PTR [rsi+0x30]
movups XMMWORD PTR [rdi+0x30],xmm3
mov rax,QWORD PTR [rsi+0x40]
mov QWORD PTR [rdi+0x40],rax
ret
nop DWORD PTR [rax+rax*1+0x0]
mp_limb_tが64ビット(x86なら32)なので,128ビットのレジスタを4つとraxを使ってコピーしている.memcpyを呼び出すまでもないらしい.
memcpyの第三引数に定数を渡してあると,たとえばmemcpy(x, y, 2434)のように書くと128ビットレジスタを上手いこと駆使してmemcpyを呼び出さないようにしていた.memcpy(x, y, 0x2434)だとさすがにjmp memcpy@pltしてた.0x2000以下だとmemcpy使わないんだね.
第三引数が定数 かつ 0x2000以下
-> memcpyを呼ばない
第三引数が変数 または 0x2001以上
-> memcpyを呼ぶ
clangではどうなるのかわからないので誰か試してほしい.