
Yoh2の日記: yoh2 += 1; 2
T/O
Yoh2さんのトモダチの日記、みんなの日記も見てね。 アナウンス:スラドとOSDNは受け入れ先を募集中です。
T/O
です。
SSIA という略語を最近覚えた。
T/O
近頃気に言っている Rust には ++ がないのでこの記法にしてみた。
mut で宣言されていたか怪しいので
let yoh2 = yoh2 + 1;
の方がよかったかな?
あー、うん。
去年忘れてた。すっかり寄付かなくなってしまった (- -;
最近前置派に宗旨替えしようとしてる。
x86系って、SIMDを明示的に使わない限り、アライメント境界が揃っていないデータ転送プログラムを書いても、パフォーマンスさえ気にしなければ特に問題ないという認識でいた。
が、実はそんな保証がないのではないかという現象に遭遇した。
それはx86_64でuint64_tの配列をコピーするコード。gcc -O3でコンパイルし、コピー元を奇数アドレスにしたらプログラムが落ちた。
試したgccは以下の3種類。いずれも現象発生。
以下、再現コード。上記コンパイラで-O2までは問題ないが-O3で落ちる。
// foo.c -- コピー関数。最適化で呼び出しが消されないようにファイルを分けた。
#include <stddef.h>
#include <stdint.h>
void copy_uint64(uint64_t *restrict dst, const uint64_t *restrict src, size_t n)
{
for(size_t i = 0; i < n; i++)
{
dst[i] = src[i];
}
}
// bar.c -- srcに奇数アドレスを設定してコピー関数呼び出し
#include <stdlib.h>
#include <stdint.h>
void copy_uint64(uint64_t *restrict dst, const uint64_t *restrict src, size_t n);
int main(void)
{
uint64_t *dst = (uint64_t *)malloc(sizeof(uint64_t) * 64);
// アライメントされていないアドレスにする。
uint64_t *src = (uint64_t *)((char *)malloc(sizeof(uint64_t) * 64 + 1) + 1);
copy_uint64(dst, src, 64);
return 0;
}
foo.cをgcc -O3 -Sしてみると、コピーしている部分と思われる箇所のアセンブリコードはこうなっていた。
movdqa (%r11,%rcx), %xmm0
addq $1, %r8
movdqu %xmm0, (%r10,%rcx)
addq $16, %rcx
srcから読み込んでいる部分がSSE命令の movdqa... 、dstに書き込んでいる部分が movdqu。
ここで曲者なのが movdqa。これは指定するアドレスが16バイト境界に揃っていなければならない命令。最適化の結果、これが使われてしまったために落ちていると思われる。
ちなみに、同じ効果を持ち、境界に揃っていなくてもよい movdqu という命令もある。このソースではdstへの書き込みで movdqu が使われている。
そのため、srcを境界整列させ、dstを奇数アドレスにした場合は問題なく実行が完了した。また、-Sで出力させたソースのmovdqaをmovdquに変更したものを使うと、srcが奇数アドレスでも問題なく実行が完了した。
最適化でSSE命令を使ってくれるのは歓迎なんだけど、アライメントなんて無視して横着したい身としてはこの最適化は厳しい。
んで結局これは (コンパイラの) バグなの? それとも (プログラムの) バグなの?
一昨年の3.11から電力不足を懸念してSETI@Homeへの参加を見合わせていたが、PCアップグレード記念 & 鯖PCの復活させたCPUの動作確認 (取り付け時にソケットにクーラーを落としてピンを曲げたということもあったし) として再開してみた。
とはいえ、電力供給能力は低下したままのはずなので、東電に余裕がないような時は自重するつもり。
BOINCstatsで現在の状況を見てみると、世界順位が、過去最高で2987位だったところが12346位、国内順位が最高が不明で現在が622位。
世界順位はともかく、国内順位が思ったより下がってなかったと感じる。私と同様に参加を中止した人が多かったんだろうか。
# そして暑い部屋が復活……
吾輩はリファレンスである。名前はまだ無い -- perlの中の人