18

ほとんどのプログラムは 4GB 未満のアドレス空間にうまく適合しますが、x64 アーキテクチャで利用可能な新しい機能を使用する必要があります。

x64 レジスタと特定の命令を使用できるが、メモリを節約するために 32 ビット ポインターを保持できるコンパイラ/プラットフォームはありますか?

レガシーコードで透過的にそれを行うことは可能ですか? それを行うためのスイッチは何ですか?

また

32 ビット ポインターを維持しながら 64 ビット機能を取得するには、コードのどのような変更が必要ですか?

4

10 に答える 10

17

これを回避する簡単な方法は、指している構造の型がほとんどない場合です。次に、データに大きな配列を割り当てて、uint32_t.

したがって、そのようなモデルの「ポインター」は、グローバル配列の単なるインデックスになります。通常、まともなコンパイラで十分に効率的であり、スペースを節約できます。たとえば、動的割り当てなど、興味のある他のものを失うことになります。

同様のことを実現する別の方法は、ポインターを実際の位置との違いでエンコードすることです。その差が常に 32 ビットに収まることを保証できれば、利益も得られます。

于 2010-11-07T11:39:15.130 に答える
5

32 ビットのインデックスとアドレスを使用する x86_64 バイナリをビルドできる、Linux X32 用に開発中の ABI があることは注目に値します。

比較的新しいだけですが、それでも興味深いものです。

http://en.wikipedia.org/wiki/X32_ABI

于 2012-08-19T02:22:55.147 に答える
4

技術的には、コンパイラがそうすることが可能です。私の知る限り、実際にはそれは行われていません。gcc 用に提案されています (ここにパッチがあっても: http://gcc.gnu.org/ml/gcc/2007-10/msg00156.html ) 。チェック済み)。私の理解では、動作させるにはカーネルと標準ライブラリからのサポートも必要です (つまり、カーネルは現在不可能な方法で物事をセットアップする必要があり、既存の 32 または 64 ビット ABI を使用してカーネルと通信することは不可能です)。 )。

于 2010-11-07T17:29:40.527 に答える
3

必要な「64ビット機能」とは正確には何ですか?それは少し曖昧ではありませんか?

答えを探しているときにこれを見つけました: http://www.codeproject.com/KB/cpp/smallptr.aspx

また、下部のディスカッションを選択してください...

これについて考える必要はまったくありませんでしたが、ポインタがどれだけのスペースを必要とするかを気にすることができることに気付くのは興味深いことです...

于 2010-11-07T22:18:52.690 に答える
2

プラットフォームによって異なります。Mac OS X では、64 ビット プロセスのアドレス空間の最初の 4 GB が予約され、マップされていません。これは、おそらく安全機能として、 32 ビット値がポインターと間違えられることがないようにするためです。試してみれば、これを打ち負かす方法があるかもしれません。格納された値に 0x100000000 を追加する C++ の「ポインター」クラスを作成することで、一度回避しました。(これは、配列へのインデックス付けよりも大幅に高速でした。これには、配列ベースのアドレスを見つけて、加算の前に乗算することも必要です。)

ISA レベルでは、32 ビット値を読み込んでゼロ拡張し、それを 64 ビット ポインターとして使用することを確実に選択できます。これは、プラットフォームが持つべき優れた機能です。

64 ビット ポインターと 32 ビット ポインターを同時に使用する場合を除き、プログラムを変更する必要はありません。nearその場合、farポインタを持っていた古き良き時代に戻っています。

また、ポインターへのポインターを使用する API との ABI の互換性が確実に失われます。

于 2010-11-07T08:37:02.283 に答える
2

x86 では、いいえ。PowerPC などの他のプロセッサでは、これは非常に一般的です。64 ビット レジスタと命令は 32 ビット モードで使用できますが、x86 では「オール オア ナッシング」になる傾向があります。

于 2010-11-07T08:59:30.697 に答える
2

これは MIPS n32 ABI: 64 ビット レジスタと 32 ビット ポインターに似ていると思います。

n32 ABI では、すべてのレジスタが 64 ビットです (したがって、MIPS64 プロセッサが必要です)。ただし、アドレスとポインタは 32 ビット (メモリに格納されている場合) のみであるため、メモリのフットプリントが減少します。32 ビット値 (ポインターなど) をレジスターにロードすると、64 ビットに符号拡張されます。プロセッサがロードまたはストアにポインタ/アドレスを使用する場合、すべての 64 ビットが使用されます (プロセッサは SW の n32-ess を認識しません)。お使いの OS が n32 プログラムをサポートしている場合 (OS も n32 モデルに従っているか、n32 サポートが追加された適切な 64 ビット OS である可能性があります)、n32 アプリケーションで使用されるすべてのメモリを適切なメモリ (下位 2GB および上位 2 GB、仮想アドレス)。このモデルの唯一の問題は、レジスタがスタックに保存されるとき (関数呼び出しなど)、すべての 64 ビットが使用され、n32 ABI に 32 ビット データ モデルがないことです。

おそらく、そのような ABI は x86-64 でも実装できます。

于 2012-02-17T17:37:59.363 に答える
1

残念ながら、ポインターのサイズが気になる場合は、より大きな問題が発生する可能性があります。ポインターの数が数百万または数十億になる場合は、実際に物理メモリまたは仮想メモリが不足する前に、Windows OS 内で制限に遭遇する可能性があります。

Mark Russinovich は、こ​​れに関連して、 Pushing the Limiting of Windows: Virtual Memoryという素晴らしい記事を書いています。

于 2010-11-07T10:26:15.517 に答える
1

Linux は現在、質問者が求めていることを正確に実行する X32 ABI をかなり包括的にサポートしています。実際、Gentoo オペレーティング システムでの構成として部分的にサポートされています。この質問は、最近の開発に照らして見直す必要があると思います。

于 2014-02-21T14:49:30.027 に答える
0

あなたの質問の2番目の部分は簡単に答えられます。実際、多くの C 実装が 32 ビット コードを使用した 64 ビット操作をサポートしている可能性が非常に高いです。これによく使用される C 型はlong long(ただし、コンパイラとアーキテクチャに確認してください)。

私の知る限り、64 ビット ネイティブ コードで 32 ビット ポインターを使用することはできません。

于 2010-11-07T08:38:17.293 に答える