質問

C ++ 03の同時実行性のメモリモデルは何ですか?

(そして、C ++ 11は同時実行性をサポートするためにメモリモデルを変更しますか?)

役に立ちましたか?

解決

C ++メモリモデルは、物理メモリがC ++コードに対していつ/なぜ書き込まれるかを指定するものです。

次のC ++標準まで、C ++メモリモデルはCと同じです。C++ 0x標準では、マルチスレッド用の適切なメモリモデルが含まれる予定です(こちら)、C規格の次のリビジョンであるC1Xの一部となる可能性があります。現在のものは初歩的なものです:

  • 現在のプログラムで観察可能なメモリ操作の動作のみを指定します。
  • 複数のプロセスが同じメモリにアクセスする場合、同時メモリアクセスについては何も言いません(共有メモリまたはプロセスの概念はありません)。
  • 複数のスレッドが同じメモリにアクセスする場合、同時メモリアクセスについては何も言いません(スレッドの概念はありません)。
  • メモリアクセスの順序を指定する方法はありません(コンパイラの最適化にはコードモーションと最近のプロセッサの再順序アクセスが含まれ、どちらも二重チェック初期化などのパターンを破ることがあります)。

したがって、現在の状態は次のとおりです。C++メモリ操作は、1つのプロセスがメインスレッドである場合にのみ指定され、変数読み取り/書き込みの特定の順序に依存するコードを記述しないでください。本質的に、これは伝統的なハローワールドプログラムとは別に、台無しにされていることを意味します。

もちろん、"今日は私のマシンで動作しますが、正しくない可能性があることを追加するように促されます。正しい文は"になります。ハードウェア、オペレーティングシステム(スレッドライブラリ)、コンパイラのこの特定の組み合わせを使用して今日は私のマシンで動作します。ポイント"

OK、これは少し厳しいですが、地獄です、 Herb Sutterでさえ認めている(イントロを読んでください)、彼は最もユビキタスなC / C ++ツールチェーンの2007年以前のバージョンについて話しています...

C ++標準委員会は、Javaのメモリモデルよりも制約が少ない(したがってパフォーマンスが優れている)一方で、これらすべての問題に対処するものを考案しようとしています。

ハンスベームは、こちらで、この問題に関する論文への指針を収集しました。 C ++委員会から。

他のヒント

他のいくつかの答えを見ると、多くのC ++プログラマーは、「メモリモデル」が何であるかを認識していないようです。手段について尋ねています。

ある意味では、メモリモデルに関する質問です。書き込み/読み取りの並べ替え(コンパイラ側またはランタイム側で発生する可能性があります)について、どのような保証(ある場合)がありますか?このようなルールがないと正しいマルチスレッドプログラムを作成することは不可能であるため、この質問はマルチスレッドプログラミングにとって非常に重要です。また、現在の明示的なメモリモデルの欠如により、 -ほとんどの場合、コンパイラーが関数呼び出し間でポインターのエイリアシングを想定していることに感謝します。 -スレッドをライブラリとして実装できない

現在のC ++には、標準のメモリモデルはありません。一部のコンパイラは、揮発性変数のメモリモデルを定義しますが、これは非標準です。 C ++ 0xは新しい「原子」を定義します;この目的のためのプリミティブ。最近のステータスが何であるかを確認するための徹底的な開始点は、スレッドとメモリモデルにあります。 C ++の場合

重要なリンクは同時実行メモリモデルアトミックタイプおよび C ++データ依存の順序付け:アトミックおよびメモリモデル標準提案。

残念ながら、C ++には「標準メモリモデル」はありません。 Javaのように。実際の実装は、コンパイラ、ランタイムライブラリ、およびプロセッサに任されています。

したがって、C ++メモリモデル==モデルの混oticとした混合マッシュです。つまり、特定のメモリモデルに依存しない安全なコードを常に作成する必要があります。コンパイラーは、順序が正しくない場合でも、クリティカルセクションの外側で必要な最適化を行うことができます。

C ++標準委員会のWebサイトで論文をチェックするのはどうですか:

共有メモリの整合性モデルについてより深く理解したい場合は、次のチュートリアルを参照してください。

http://rsim.cs.uiuc.edu/~sadve /Publications/computer96.pdf

簡単な答え:なし

長答:C ++には管理メモリがありません。自分で割り当てて解放する必要があります。スマートポインタクラスを使用すると、この負担を軽減できます。割り当てたメモリを解放するのを忘れると、それはメモリリークとバグになります。メモリを解放した後にメモリを使用しようとする場合、またはメモリを2回以上解放しようとする場合、これらも厄介なバグです。

低レベルの詳細に関しては、C ++はそれを指定していません-ハードウェア次第です。メモリは、ある種のメモリアドレスを含むポインタを介してアクセスされます。メモリアドレスは、物理アドレスでも仮想アドレスでもかまいません。物理アドレスは、オペレーティングシステムカーネルで作業している場合、またはリアルモードで実行された古いDOSコードを読んでいる場合にのみ表示されます。詳細については、仮想メモリをご覧ください。多くの優れたリソースがあります。

x86アーキテクチャでは、セグメント記述子を使用してメモリをアドレス指定することもできます。これは、Win16の時代から実際に使用されていないワームの別の缶です。運が良ければ、対処する必要はありません。

一言で言えば、C ++メモリモデルは...で構成されています...

  • 下向きに成長するスタック-つまり、スタックフレームをプッシュすると、スタックポインターの値はそれよりも小さくなります

  • 上方に増加するヒープ。つまり、新しく割り当てられたメモリの終了アドレスは、メモリの前よりも大きくなります。ヒープにメモリを割り当てるには、malloc()またはnewを使用します。ヒープに十分なメモリがない場合、malloc(またはnew)はシステム関数brk()sbrk()を呼び出してヒープのサイズを増やします。 brk()またはsbrk()の呼び出しが失敗した場合、mallocまたはnewはメモリ不足例外で失敗します。

スタックまたはヒープが上下するかどうかを気にする必要はありません。一部のシステムでは、これらが逆に動作する場合があります。スタックとヒープがアドレス空間の端から内側に成長することを考えてください。

  • メモリアロケータmallocは、8ビットバイト単位でメモリを割り当てます。 Newはメモリも割り当てますが、割り当てるメモリの量は、更新されるオブジェクトのサイズに基づきます。

  • 実行可能コードを含むテキストスペース。テキストはヒープの下にあります。実行中にテキストスペースを変更することはできません

プログラムには、テキストの下に他の特別な目的のセクションがある場合があります。

Linuxシステムでobjdumpを使用して、プログラムがどのように静的に編成されるか(ロードされる前)を確認できます。

質問では言及していませんが、"並行性"この質問に割り当てたキーワードの1つです。スレッディングシステムは、各スレッドのヒープに追加のスレッドスペースを割り当ててから、スタックポインターを管理してスレッドを切り替えます。

さらに詳細があり、その多くは特定のハードウェア、OS、またはスレッドシステムに固有のものですが、それは本質的なアイデアです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top