web-dev-qa-db-ja.com

64ビットマシンでのC ++ intとlong long

私のコンピューターには64ビットプロセッサが搭載されており、sizeof(int)sizeof(long)、およびsizeof(long long)を検索すると、intおよび- longは32ビット、long longは64ビットです。その理由を調査したところ、C++のintがマシンのWordサイズに適合するという一般的な仮定は間違っているようです。私が理解したように、サイズを定義するのはコンパイラ次第であり、私のものはMingw-w64です。私の研究の理由は、Wordサイズよりも小さい型の使用が速度に有益である場合(たとえば、short =vs int)またはそれが悪影響を与えるかどうか。 32ビットシステムでの一般的な意見の1つは、Wordのサイズがintであるため、shortintに変換され、追加のビットシフトなどが発生し、パフォーマンスが低下します。反対の意見は、キャッシュレベルには利点がある(私はそれについて深く掘り下げなかった)ことであり、shortを使用することは仮想メモリの節約に役立つでしょう。したがって、このジレンマの間の混乱に加えて、別の問題にも直面します。私のシステムは64ビットで、intまたはshortのどちらを使用しても問題ありませんが、それでもWordサイズよりも小さいため、私はそうは思わないでしょう。 64ビットlong longを使用するのが効率的です。これは、システムが設計されているレベルであるためです。また、タイプサイズを定義するOSのライブラリ(ILP64、LP64)があるという別の制約があることも読みました。 ILP64のデフォルトintは、LP64とは対照的に64ビットですが、ILP64をサポートするOSを使用すると、プログラムが高速化しますか? C++プログラムを高速化するためにどのタイプを使用すべきかを尋ね始めたとき、専門知識がなく、いくつかの説明が互いに矛盾しているように見える、より深いトピックに直面しました。説明していただけますか:

1)1〜4バイトのデータでも最大のパフォーマンスを達成するためにx-64でlong longを使用することがベストプラクティスである場合

2)Wordサイズ未満のタイプを使用する場合のトレードオフ(メモリの使用と追加の操作)

3)Word&intサイズが64ビットのx64コンピューターは、いわゆる下位互換性を使用して、16ビットのWordサイズを使用してshortを処理する可能性がありますか?または、16ビットファイルを64ビットファイルに入れる必要があり、それを実行できるという事実により、システムは下位互換性があると定義されます。

4)int 64ビットにするようコンパイラーに強制できますか?

5)LP64を使用するPCにILP64を組み込む方法

6)他のコンパイラ、OS、およびアーキテクチャ(32ビットプロセッサ)で上記の問題に適応したコードを使用することで起こりうる問題は何ですか?

17
UserRR

1)1〜4バイトのデータでも最大のパフォーマンスを達成するためにx64でlong longを使用するのがベストプラクティスである場合

いいえ、それはおそらくあなたのパフォーマンスを悪化させるでしょう。たとえば、64ビット整数を使用していて、32ビット整数を使用できなかった場合、プロセッサとメモリの間で送信する必要のあるデータ量が2倍になり、メモリの桁数が大幅に遅くなります。すべてのキャッシュとメモリバスは2倍の速さで処理されます。

2)Wordサイズ未満のタイプを使用する場合のトレードオフ(メモリの使用と追加の操作)

一般に、最近のマシンのパフォーマンスを左右する主な要因は、プログラムを実行するために格納する必要があるデータの量です。プログラムのワーキングセットサイズがレジスタ、L1キャッシュ、L2キャッシュ、L3キャッシュ、RAMの順にこの容量を超えると、パフォーマンスが大幅に低下します。

さらに、コンパイラーがプロセッサーのベクトル命令(別名SSE命令)の使用方法を理解できるほど賢い場合は、より小さなデータ型を使用することでメリットがあります。最新のベクトル処理ユニットは十分にスマートです8つの16ビット短整数を2つの64ビット長長整数と同じスペースに詰め込むため、一度に4倍の演算を実行できます。

3)Word&intサイズが64ビットのx64コンピュータは、いわゆる下位互換性を使用して、16ビットのWordサイズを使用してshortを処理する可能性がありますか?または、16ビットファイルを64ビットファイルに入れる必要があり、それを実行できるという事実により、システムは下位互換性があると定義されます。

ここで何を求めているのかわかりません。一般的に、64ビットマシンは、32ビットおよび16ビットの実行可能ファイルを実行できます。これは、これらの以前の実行可能ファイルが64ビットマシンの潜在的なサブセットを使用するためです。

ハードウェア命令セットは一般に下位互換性があります。つまり、プロセッサ設計者は機能を追加する傾向がありますが、機能を削除することはほとんどありません。

4)コンパイラにintを64ビットにすることを強制できますか?

すべてのコンパイラーには、固定ビットサイズのデータ​​を操作できるかなり標準的な拡張機能があります。たとえば、ヘッダーファイルstdint.hは、int64_tuint64_tなどの型を宣言します。

5)LP64を使用するPCにILP64を組み込む方法

https://software.intel.com/en-us/node/528682

6)上記の問題に適応したコードを他のコンパイラ、OS、およびアーキテクチャ(32ビットプロセッサ)で使用すると、どのような問題が発生する可能性がありますか?

一般に、コンパイラーとシステムは、特定のシステムでコードを実行する方法を理解するのに十分なほどスマートです。ただし、32ビットプロセッサは、64ビットデータを操作するために追加の作業を行う必要があります。つまり、正確さは問題ではありませんが、パフォーマンスは問題になります。

ただし、一般的にパフォーマンスが非常に重要な場合は、とにかく特定のアーキテクチャとプラットフォーム用にプログラミングする必要があります。

説明リクエスト:どうもありがとうございます!質問番号を明確にしたいと思いました:1。あなたはそれが記憶に悪いと言います。 32ビット整数の例を見てみましょう。それをメモリに送信すると、64ビットシステムであるため、目的の整数0xee ee ee eeに対して、送信すると0x ee ee ee ee + 32の他のビットになりますか?ワードサイズが64ビットの場合、プロセッサはどのように32ビットを送信できますか? 32ビットが望ましい値ですが、32ビットの未使用ビットと組み合わせてこの方法で送信しませんか?私の仮定が正しい場合は、メモリに違いはありません。

ここでは、2つの点について説明します。

まず、あなたが議論する状況は起こりません。プロセッサは、適切に使用するために32ビット値を64ビット値に「昇格」する必要はありません。これは、最新のプロセッサにはさまざまなサイズのデータ​​を適切に処理できるさまざまなアクセスモードがあるためです。

たとえば、64ビットIntelプロセッサにはRAXという名前の64ビットレジスタがあります。ただし、この同じレジスタは、EAXとして参照することにより、32ビットモードでも、16ビットモードや8ビットモードでも使用できます。ここから図を盗みました:

x86_64レジスタrax/eax/ax/alがレジスタの内容全体を上書き

1122334455667788
================ rax (64 bits)
        ======== eax (32 bits)
            ====  ax (16 bits)
            ==    ah (8 bits)
              ==  al (8 bits)

コンパイラとアセンブラの間で、32ビット値が適切に処理されるように正しいコードが生成されます。

次に、メモリのオーバーヘッドとパフォーマンスについて話しているときは、より具体的にする必要があります。現代のメモリシステムは、ディスク、メインメモリ(RAM)、通常は2つまたは3つのキャッシュ(L3、L2、L1など)で構成されています。ディスクでアドレス指定できるデータの最小量はページと呼ばれ、ページサイズは通常4096バイトです(ただし、あります)。次に、メモリ内でアドレス指定できる最小量のデータはキャッシュラインと呼ばれ、通常32ビットまたは64ビットよりはるかに大きくなります。私のコンピューターでは、キャッシュラインのサイズは64バイトです。プロセッサは、データが実際に転送され、Wordレベル以下でアドレス指定される唯一の場所です。

したがって、ディスク上にあるファイル内の64ビットWordを1つ変更する場合、私のコンピューターでは、実際にはディスクから4096バイトをメモリにロードし、次にメモリから64バイトをL3、L2にロードする必要があります。 、およびL1キャッシュ、そしてプロセッサはL1キャッシュから単一の64ビットワードを取得します。

その結果、Wordサイズはメモリ帯域幅には何も意味しません。ただし、これらの32ビット整数のうち16個を、それらの64ビット整数のうち8個をパックできる同じスペースに収めることができます。または、同じ空間に32個の16ビット値または64個の8ビット値を収めることもできます。プログラムで多数の異なるデータ値を使用する場合、必要な最小のデータ型を使用することでパフォーマンスを大幅に向上させることができます。

33
David