問題タブ [memory-alignment]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - クラス/構造体のメンバーは、宣言された順序で常にメモリ内に作成されますか?
これは、 Rob Walkerの回答hereによって引き起こされた質問です。
次のようにクラス/構造体を宣言するとします。
これらのメンバーがメモリ内で正確にその順序で宣言されると想定しても安全ですか、それともコンパイラに依存するものですか? 私が質問しているのは、コンパイラがそれらを使って何でもできるといつも思っていたからです。
これは私の次の質問につながります。上記の例でメモリ アラインメントの問題が発生する場合、コンパイラはそれを暗黙的に次のように変換できないのはなぜですか。
(私は主に C++ について質問していますが、C の回答も聞きたいです)
関連トピック
memory - メモリアライメントの目的
確かにわかりません。1バイトの長さのメモリワードを持つメモリがあるとします。アラインされたアドレスの場合のように、アラインされていないアドレス(つまり、4で割り切れない)の単一メモリアクセスで4バイト長の変数にアクセスできないのはなぜですか?
64-bit - コードを 64 ビットに移植するための構造のアライメント
C 層に PInvokes する 32 ビット .NET アセンブリがあります。このアセンブリを 64 ビットに移植したいと考えています。私は 64 ビットへの移植に関連する多くの文書を読みましたが、そのすべてが、構造体を使用する場合は位置合わせに注意する必要があることを示唆しているようです。
構造のアラインメントに関連する一般的な質問があり、何も見逃さないように最初にそれを明確にしたかったのです。
構造体ポインターを受け入れ、基本的に内部の値を埋める C エントリ ポイントがあるとします。この C コードにはパッキング ディレクティブがなく、すべての .NET 構造体が pack=8 に配置されています。したがって、隣接する int を持つ構造体を渡すと、.NET レイヤーに入力されたデータの解釈に問題がある可能性があると考えました。C はデフォルトで pack=4 を使用し、.NET では構造体を pack=8 として解釈しているためです。レイヤーなので、問題が発生する可能性があると考えました。しかし、そうではないようです。データはうまく解釈されているようです。
誰でもこの動作を説明できますか?
ありがとう、ニランジャン
macos - Mac ABI が x86-32 に対して 16 バイトのスタック アラインメントを必要とするのはなぜですか?
古い PPC RISC システムや x86-64 の場合でも、この要件は理解できますが、実証済みの古い x86 の場合は? この場合、スタックは 4 バイト境界のみで整列する必要があります。はい、一部の MMX/SSE 命令では 16 バイトのアラインメントが必要ですが、それが呼び出し先の要件である場合は、アラインメントが正しいことを確認する必要があります。この追加の要件をすべての発信者に負担させるのはなぜですか? すべての呼び出しサイトがこの要件を管理する必要があるため、実際にはパフォーマンスが低下する可能性があります。何か不足していますか?
更新:これについてさらに調査し、社内の同僚と相談した結果、私はこれについていくつかの仮説を立てました。
- OS の PPC、x86、および x64 バージョン間の一貫性
- GCC codegen は、単純に「プッシュ」命令を実行するのではなく、sub esp,xxx を一貫して実行し、データをスタックに「移動」するようになりました。これは、一部のハードウェアでは実際に高速になる可能性があります。
- これは呼び出しサイトを少し複雑にしますが、呼び出し元がスタックをクリーンアップするデフォルトの "cdecl" 規則を使用する場合、余分なオーバーヘッドはほとんどありません。
最後の項目で私が抱えている問題は、呼び出し先がスタックをクリーニングすることに依存する呼び出し規則の場合、上記の要件がコード生成を実際に「醜く」することです。たとえば、一部のコンパイラが内部使用 (つまり、他の言語やソースからの呼び出しを意図していないコード) のために、より高速なレジスタ ベースの呼び出しスタイルを実装することを決定したものは何ですか? このスタックアライメントの問題は、いくつかのパラメーターをレジスターに渡すことによって達成されるパフォーマンスの向上の一部を無効にする可能性があります。
更新:これまでのところ、唯一の本当の答えは一貫性でしたが、私にはそれは少し簡単すぎる答えです。私は x86 アーキテクチャに関して 20 年以上の経験がありますが、パフォーマンスやその他の具体的なものではなく、一貫性が本当に理由である場合、開発者がそれを必要とするのは少しナイーブであることを丁重に提案します。彼らは、30 年近くにわたるツールとサポートを無視しています。特に、ツール ベンダーがツールを自社のプラットフォームにすばやく簡単に適応させることを期待している場合 (おそらくそうではないかもしれません... それはApple です...)
このトピックは別の日かそこらにあげて、閉じます...
関連している
c++ - カスタムC++アロケータの説得力のある例?
std::allocator
カスタムソリューションを支持するために捨てる本当に良い理由は何ですか?正確性、パフォーマンス、スケーラビリティなどに絶対に必要な状況に遭遇したことがありますか?本当に賢い例はありますか?
カスタムアロケータは、私があまり必要としなかった標準ライブラリの機能でした。ここSOの誰かが、彼らの存在を正当化するための説得力のある例を提供できるかどうか疑問に思っていました。
c - スタック変数は GCC __attribute__((aligned(x))) によって整列されていますか?
私は次のコードを持っています:
そして、私は次の出力を持っています:
のアドレスがa[0]
の倍数ではないのはなぜ0x1000
ですか?
正確に__attribute__((aligned(x)))
は何ですか?この説明を誤解していませんか?
gcc 4.1.2 を使用しています。
visual-c++ - Visual C++ 2008 での構造体メンバーの配置
Visual C++ では、プロジェクトのプロパティ ページで構造体メンバー alignemnt を選択できます。問題は、この構成がプロジェクト内のすべての構造に使用されていることです。
特定の構造体のメンバーアラインメントを個別に設定する方法はありますか (VC++ 固有だと思います)。
c++ - アライメントされたメモリアクセスとアライメントされていないメモリアクセス?
アライメントされたメモリアクセスとアライメントされていないメモリアクセスの違いは何ですか?
私は TMS320C64x DSP で作業しており、組み込み関数 (アセンブリ命令用の C 関数) を使用したいと考えています。
where_amem2
は 2 バイトのアライメントされたアクセスを行い、_mem2
アライメントされていないアクセスを行います。
いつどれを使用する必要がありますか?
c++ - 固定サイズのメモリ境界上のネイティブ コードを GCC/G++/AS に合わせますか?
バイトコード インタープリターのバイトコードを実装するすべてのコードを含む C 関数があります。
バイトコードの値からジャンプするアドレスを直接計算できるように、メモリ内のコンパイル済みコードのセグメントを固定サイズの境界に揃える方法があるかどうか疑問に思っています。配列と同じように機能しますが、計算されたアドレスから読み取る代わりに、それにジャンプしています。
すべての「バイトコード コード」セグメントの最後に次のジャンプを実行するコードを配置する必要があること、および境界サイズを少なくとも最大セグメントのサイズと同じ大きさにする必要があることを認識しています。
これが可能である場合、コンパイラ/アセンブラ (gcc / g++ / as) にどのようにアラインするように指示しますか?