パスワードを忘れた? アカウント作成
7324358 journal
プログラミング

Yoh2の日記: アライメント揃ってなくても大丈夫だというのは思い込み? 12

日記 by Yoh2

x86系って、SIMDを明示的に使わない限り、アライメント境界が揃っていないデータ転送プログラムを書いても、パフォーマンスさえ気にしなければ特に問題ないという認識でいた。
が、実はそんな保証がないのではないかという現象に遭遇した。
それはx86_64でuint64_tの配列をコピーするコード。gcc -O3でコンパイルし、コピー元を奇数アドレスにしたらプログラムが落ちた。

試したgccは以下の3種類。いずれも現象発生。

  • gcc-4.6.x (詳細忘れ。Ubuntu 12.04)
  • gcc-4.6.3 (Gentoo)
  • gcc-4.7.2 (Gentoo)

以下、再現コード。上記コンパイラで-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命令を使ってくれるのは歓迎なんだけど、アライメントなんて無視して横着したい身としてはこの最適化は厳しい。

んで結局これは (コンパイラの) バグなの? それとも (プログラムの) バグなの?

7319116 journal
日記

Yoh2の日記: SETI@Home仮復帰

日記 by Yoh2

一昨年の3.11から電力不足を懸念してSETI@Homeへの参加を見合わせていたが、PCアップグレード記念 & 鯖PCの復活させたCPUの動作確認 (取り付け時にソケットにクーラーを落としてピンを曲げたということもあったし) として再開してみた。
とはいえ、電力供給能力は低下したままのはずなので、東電に余裕がないような時は自重するつもり。

BOINCstats現在の状況を見てみると、世界順位が、過去最高で2987位だったところが12346位、国内順位が最高が不明で現在が622位。
世界順位はともかく、国内順位が思ったより下がってなかったと感じる。私と同様に参加を中止した人が多かったんだろうか。

# そして暑い部屋が復活……

typodupeerror

吾輩はリファレンスである。名前はまだ無い -- perlの中の人

読み込み中...