スイッチがどのように機能するかを知りたいと思って/LARGEADDRESSAWARE
いますが、実装の詳細についてはあまり見つけることができません。
スイッチが使用されたときに何が起こっているのか、その結果を説明できる人はいますか (プロセスがより多くのメモリにアクセスできるようにすることは別として)。
スイッチがどのように機能するかを知りたいと思って/LARGEADDRESSAWARE
いますが、実装の詳細についてはあまり見つけることができません。
スイッチが使用されたときに何が起こっているのか、その結果を説明できる人はいますか (プロセスがより多くのメモリにアクセスできるようにすることは別として)。
歴史的に、32 ビット Windows システムは、プロセスのアドレス空間の下位 2 GB のみがアプリケーションによって使用される仮想メモリ レイアウトを持っていました。上位 2 GB はカーネル用に予約されます。これは文書化された動作でした。明示的にオプトインしない限り、文書化された動作を変更することはクールではありません。それ/LARGEADDRESSAWARE
がそのためです。これは、プログラムが 2GB 境界を超えるアドレスを使用してもかまわないことをシステムに通知する、実行可能ヘッダー内のフラグをトリガーします。そのフラグを使用すると、システムは下位 3 GB からアドレスを割り当てることができ、上位 1 GB はカーネル用です。
これが重大な変更になるようにアプリをどのようにコーディングする必要があるかは、まったく別の問題です。アドレスを signed int にキャストして比較する人もいるかもしれません。アドレスにビット 31 が設定されていると、これは壊れます。
編集: スイッチ自体によるパフォーマンスへの影響はありません。ただし、アプリケーションで 2 GB を超えるメモリ負荷が定期的に発生する場合は、より積極的にキャッシュすることでパフォーマンスを向上させることができます。3GB スイッチがないと、アプリは 2GB を超える仮想メモリを消費できません。スイッチで3つまで。
Venice、Sphereおよび100kデータセットでSLAM++ライブラリを使用して簡単なベンチマークを実行しました。
Dataset | Time x86 | Time x86 /LARGEADDRESSAWARE | Time x64
Venice | bad_alloc | 4276.524971 | 300.315826 sec
Sphere | 2.946498 | 3.605073 | 1.727466 sec
100k | 46.402400 | 50.196711 | 32.774384 sec
すべての時間は秒単位です。これで、パフォーマンスの負担がかなり大きくなる可能性があります。これは主にBLAS操作を行っており、SSEを使用して高速化することもあり、全体がかなりメモリバウンドです。x86 でのVeniceのピーク時のメモリ使用量は3.5 GB をわずかに上回り (x64 システムでは最大 4 GB になる可能性があると思います)、x64 では 4.3 GB を少し下回りました。他のデータセットのメモリ使用量ははるかに少なく、2 GB をはるかに下回っています。
Venice/LARGEADDRESSAWARE
上の x86 の場合、データがアクセスされたときにメモリー使用量が 3 GB を超えたにもかかわらず、OS が 2 GB を超える領域のほとんどをページング・ファイルに保持しようとしているように見えました。 . また、x86 に比べて x64 の算術演算にはいくつかの利点があります (プログラムは追加のレジスタを使用できるなど)。これがおそらく、小さなデータセットで通常の x86 が x64 よりも遅い理由です。
これは、2x AMD Opteron 2356 SEと 16 GB の 667 MHz DDR2 を搭載し、Windows Server 2003 x64 を実行するマシンで測定されました。
Windows 7、Intel Core i7-2620M、8 GB 1333 MHz DDR3 マシン:
Dataset | Time x86 | Time x86 /LARGEADDRESSAWARE | Time x64
Venice | bad_alloc | 203.139716 | 115.641463 sec
Sphere | 1.714962 | 1.814261 | 0.870865 sec
100k | 18.040907 | 18.091992 | 13.660002 sec
これは非常によく似た動作をします。x64 は x86 よりも高速であり、/LARGEADDRESSAWARE
低速です (ただし、前のケースほど遅くはありませんが、CPU または OS に依存する可能性があります)。
/LARGEADDRESSAWARE
コード生成には影響しないため、パフォーマンスへの影響はありません。
このフラグを設定しないプログラムは、仮想メモリ アドレス < 2^31 しか取得しません。このフラグが設定されたプログラムは、2^31 を超える仮想アドレスを取得する可能性があります。
符号付き整数演算に依存するプログラムには微妙なバグがある可能性があるため、これは重要です。
例: int へのポインタ キャスト:
void* p0 = ...; // from somewhere
void* p1 = ...; // from somewhere else
assert( p1 > p0 );
int diff = (int)p1 - (int)p0;
これは、2 GB を超えるアドレスが存在すると壊れます。したがって、控えめに言うと、OS はこのフラグが設定されていないプログラムを扱います。「2 GB を超えるアドレスに遭遇したときに何か悪いことをする可能性がある」からです。
一方、x86 システムでは、/3GB
フラグを設定すると、カーネルが使用できる仮想メモリの量が減少し、パフォーマンスに影響を与える可能性があります。