6

単純な問題のためにJava、Python、またはC ++でプログラミングしているとしましょう。これは、TCP/UDPエコーサーバーの構築または階乗の計算である可能性があります。アーキテクチャの詳細、つまり32ビットか64ビットかを気にする必要がありますか?

私見ですが、かなり低レベルのものをプログラミングしているのでない限り、32ビットか64ビットかを気にする必要はありません。どこが間違っているのですか?または私は正しいですか?

4

11 に答える 11

16

ほとんどの状況で正しい

ワードサイズまたは低レベルのバイナリを直接処理しない限り、ランタイム/言語/コンパイラはこれらの詳細を抽象化します。

バイトオーダーでさえ、カーネルのNIC/ネットワークスタックによって抽象化されます。それはあなたのために翻訳されています。Cでソケットをプログラミングする場合、データを送信するときにネットワークのバイト順序を処理する必要がある場合がありますが、32ビットまたは64ビットの違いは関係ありません。

バイナリデータのブロブを処理する場合、あるアーキテクチャから別のアーキテクチャにマッピングすると(たとえば、C構造体へのオーバーレイとして)、他の人が述べているように問題が発生する可能性がありますが、これが文字などに基づいてアーキテクチャに依存しないプロトコルを開発する理由です。

実際、Javaのようなものは、マシンを別のステップで抽象化する仮想マシンで実行されます。

アーキテクチャの命令セットと、それに構文がどのようにコンパイルされるかについて少し知っていると、プラットフォームを理解し、よりクリーンでタイトなコードを作成するのに役立ちます。コンパイラを勉強した後、古いCコードにしかめっ面をしていることを知っています!

于 2009-06-25T20:34:25.887 に答える
16

仮想マシンがどのように機能するか、プラットフォーム上でどのように機能するか、または特定のC ++構造がアセンブリにどのように変換されるかを知ることで、常に優れたプログラマーになります。それは。

キャッシュミスとは何か、そしてそれらがプログラムに影響を与える可能性がある理由を知るには、メモリなどを理解する必要があります。インターフェースまたは高レベルの方法でしか使用できない場合でも、特定のものがどのように実装されているかを知っておく必要があります。それがどのように機能するかを知ることで、最善の方法でそれを実行できます。

パケット作業の場合、データがプラットフォームに保存される方法と、データをネットワーク経由で別のプラットフォームに送信すると、データの読み取り方法(エンディアン)がどのように変わるかを理解する必要があります。

コンパイラーは、コンパイルしているプラ​​ットフォームを最大限に活用します。標準とコードをしっかりと守っている限り、ほとんどのことを無視して、コンパイラーが最良のものを作成すると想定できます。

要するに、違います。低レベルのものを知る必要はありませんが、知ることは決して痛いことではありません。

于 2009-06-25T20:37:48.373 に答える
8

前回Java言語の仕様を見たとき、整数ボクシングのセクションにばかげた落とし穴が含まれていました。

Integer a = 100;
Integer b = 100;

System.out.println(a == b);

それは印刷することが保証されていますtrue

Integer a = 300;
Integer b = 300;

System.out.println(a == b);

を印刷することは保証されていませんtrue。ランタイムによって異なります。スペックは完全に開いたままにしました。これは、intを-128から127の間にボックス化すると、「インターン」オブジェクトが返されるためです(文字列リテラルがインターンされる方法に類似しています)が、言語ランタイムの実装者は、必要に応じてその制限を上げることをお勧めします。

私は個人的にそれを非常識な決定だと考えており、それ以来、彼らがそれを修正したことを願っています(一度書いて、どこでも実行しますか?)

于 2009-06-25T20:53:07.050 に答える
6

あなたは時々わざわざしなければなりません。

これらの低レベルの詳細が突然飛び出してあなたを噛んだとき、あなたは驚くことができます。たとえば、Javadoubleは64ビットに標準化されています。ただし、Linux JVMは、doubleがCPUレジスタにある限り80ビットである場合、「拡張精度」モードを使用します。これは、次のコードが失敗する可能性があることを意味します。

double x = fun1();
double y = x;

System.out.println(fun2(x));

assert( y == x );

yがレジスタからメモリに強制的に出され、80ビットから64ビットに切り捨てられるからです。

于 2009-06-25T20:46:39.463 に答える
3

JavaとPythonでは、アーキテクチャの詳細が抽象化されているため、アーキテクチャに依存するコードを作成することは実際には多かれ少なかれ不可能です。

C ++では、これはまったく別の問題です。アーキテクチャの詳細に依存しないコードを記述できますが、特に、などのアーキテクチャに依存する基本的なデータ型に関する落とし穴を避けるように注意してくださいint

于 2009-06-25T20:40:07.433 に答える
2

あなたが正しく物事を行う限り、あなたはほとんどの言語について知る必要はほとんどありません。多くの場合、言語の動作は変わらないため、知る必要はありません(たとえば、Javaは実行時の動作を正確に指定します)。

C ++およびCでは、物事を正しく行うことには、intについての仮定を行わないことが含まれます。ポインタをintに入れないでください。メモリサイズやアドレスで何かをするときは、size_tとptrdiff_tを使用してください。データ型のサイズを当てにしないでください。intは少なくとも16ビットである必要があり、ほとんどの場合32であり、一部のアーキテクチャでは64である可能性があります。浮動小数点演算が異なるマシンでまったく同じ方法で実行されると想定しないでください(IEEE標準にはある程度の余裕があります)。

ネットワークをサポートするほとんどすべてのOSは、起こりうるエンディアンの問題に対処するための何らかの方法を提供します。それらを使用してください。文字の算術演算(EBCDICのような奇妙なものかもしれません)ではなく、isalpha()などの言語機能を使用して文字を分類します。(もちろん、文字タイプとしてwchar_tを使用し、内部でUnicodeを使用するのが一般的になりました。)

于 2009-06-25T20:46:48.683 に答える
1

PythonまたはJavaでプログラミングしている場合、インタープリターと仮想マシンはそれぞれアーキテクチャのこのレイヤーを抽象化します。その場合、32ビットまたは64ビットのアーキテクチャで実行されているかどうかを心配する必要はありません。

C ++についても同じことは言えません。この場合、32ビットまたは64ビットのマシンで実行しているかどうかを自問する必要があります。

于 2009-06-25T20:39:10.807 に答える
0

javaと.netを使用すると、ビットをいじるなどの非常に低レベルの作業を行わない限り、実際に気にする必要はありません。c、c ++、fortranを使用している場合はうまくいくかもしれませんが、実際には、明示的にするためにuint64_tやuint32_tなどの決定的な宣言を使用する「stdint.h」などを使用することをお勧めします。また、リンク方法に応じて、特にライブラリを使用してビルドする必要があります。たとえば、64ビットシステムでは、デフォルトの64ビットコンパイルモードでgccを使用する場合があります。

于 2009-06-25T21:12:29.600 に答える
0

生のC構造体を次のようにネットワーク経由で送受信する場合にのみ、「エンディアンネス」に注意する必要があります。

ret = send(socket、&myStruct、sizeof(myStruct));

ただし、これは推奨される方法ではありません。

当事者のマシンアーキテクチャに関係がないように、当事者間でプロトコルを定義することをお勧めします。

于 2009-06-25T20:34:35.840 に答える
0

C ++では、32ビットまたは64ビットで無差別に機能するコードを記述したい場合は、十分に注意する必要があります。int多くの人は、たとえば、それがポインタを格納できると誤って想定しています。

于 2009-06-25T20:35:52.997 に答える
0

32ビットマシンでは、最大4GBのアドレス可能な仮想メモリを使用できます。(実際には、それよりもさらに小さく、通常はOSとさまざまなリンカーオプションに応じて2GBまたは3GBです。)64ビットマシンでは、巨大な仮想アドレス空間を使用できます(実際には、ディスクによってのみ制限されます)。 )そしてかなりひどい大きなRAM。

したがって、計算に6GBのデータセットが必要な場合(たとえば、一貫性のないアクセスが必要で、一度に少しずつストリーミングできないものなど)、64ビットアーキテクチャでは、RAMに読み込んで処理を実行できます。一方、32ビットアーキテクチャでは、データセット全体を常駐させるオプションがないため、根本的に異なる方法でアプローチする必要があります。

于 2009-06-25T23:43:56.313 に答える