doubleを-malign-doubleオプションで8バイトアラインメントにするメリットはなんでしょうか？


doubleを-malign-doubleオプションで8バイトアラインメントにする具体的なメリットはなんでしょうか？




[gcc マニュアル x86](https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html) によると

  * `double` `long double` `long long` を３２ビット境界に載せるか６４ビット境界に載せるかが変わる
  * Pentium 等では少し高速化する（少量のメモリの犠牲と引き換えに）
  * `x86-64` ではデフォルトで有効

とあります。最後の項は微妙に不正確というか `x86-64` では常に `-malign-double` が有効で `-mno-align-double`
は無効化されています。

で、何が嬉しいのかというと、その辺はハードウエア仕様を知らないと理解しがたいです。厳密さに目をつぶっておおまかな話をすると

  * 32bit CPU というのはバス幅が 32bit です。よって１回のバスアクセスで 32bit の値を読み書きすることができます。つまり `double` １つの読み書きには２回のバスアクセスが必要です。
  * 64bit CPU というのはバス幅が 64bit です。よって１回のバスアクセスで 64bit の値を読み書きすることができます。つまり `double` １つの読み書きには１回のバスアクセスが必要です。

上記の話が成立するのは整合がとれている場合に限ります。 64bit な値つまり `double` が 64bit
に整合していないと、バスアクセスが２回必要になるのは理解できるでしょうか？図示するとわかりやすいんですが AA 下手なので略。

というわけで「整合をとると、ハードウエア的にバスアクセス回数が減るので高速化できる」というのが答えとなります。

`-malign-double` なオブジェクトと `-mno-align-double` なオブジェクトは (x86 32bit では) `struct`
等の整合が違ってしまい非互換になるので混ぜるな危険です。

* * *

なんかうまく説明しきっていない気がしたので追記

32bit CPU と 32bit OS/アプリの組み合わせでは `-malign-double`
を指定してもしなくても速度に一切変化がない（バスアクセス回数に変わりはない）わけです。混ぜるな危険の分、指定しないほうが無難そうです。

64bit CPU と 32bit OS/アプリの場合のみ、バスアクセス回数が１減る可能性が高まり（ `-malign-double` を指定していなくても
64bit 境界に載っていることは普通にあるので常に効果があるわけではない）その分高速になる、のでしょうが x86 では L1 cache
のアクセス回数が１減っても体感できるほどの差は出ません。

64bit CPU と 64bit OS/アプリの場合は最初から `-malign-double` は有効で、無効化できませんのでそもそも違いがないし。

ということで体感できる差が出るとしたら

  * ハード的には 64bit CPU が普及したがソフトはまだ 32bit が主流な短期間だけ
  * `double` の演算をひたすら繰り返す数値解析ソフト (32bit) を使う

時くらいです（真の逸般人ならソフトも即 64bit に移行しているはずなので、この状況に該当するとしたらえせ逸般人であろう）。

一般人が一般的な使い方する分には目に見えるほどの速度向上効果は望めず、メモリ消費量だけ微妙に増え、ということでメリットはあまり体験できず、 `struct`
が ABI
非互換になるデメリットだけありそうです。コンパイラ実装者は当然その辺全部理解しているので、デフォルトで有効になっていないコンパイルオプションにはそれなりの理由がきっちりあります。それをあえて我々末端ユーザーが指定するときにはリスクとメリットを理解したうえで行うことが大事です。

