C ++ 11では、標準化されたメモリモデルが導入されました。どういう意味ですか?そして、それはC ++プログラミングにどのように影響しますか?

1966
Nawaz 2011-06-12 13:30.

C ++ 11は標準化されたメモリモデルを導入しましたが、それは正確にはどういう意味ですか?そして、それはC ++プログラミングにどのように影響しますか?

この記事(ハーブサッターを引用しているGavin Clarkeによる)は、次のように述べています。

メモリモデルは、C ++コードに、コンパイラの作成者や実行中のプラットフォームに関係なく呼び出す標準化されたライブラリがあることを意味します。さまざまなスレッドがプロセッサのメモリと通信する方法を制御する標準的な方法があります。

「標準にある異なるコア間で[コード]を分割することについて話しているとき、私たちはメモリモデルについて話している。人々がコードで行う以下の仮定を破ることなくそれを最適化するつもりだ」とサッター氏は語った。

ええと、私はオンラインで利用できるこの段落と同様の段落を覚えることができ(私は生まれてから自分の記憶モデルを持っていたので:P)、他の人からの質問への回答として投稿することもできますが、正直なところ、私は正確には理解していませんこの。

C ++プログラマーは以前からマルチスレッドアプリケーションを開発していましたが、それがPOSIXスレッド、Windowsスレッド、またはC ++ 11スレッドであるかどうかはどのように重要ですか?メリットは何ですか?低レベルの詳細を理解したい。

また、C ++ 11メモリモデルは、C ++ 11マルチスレッドのサポートに何らかの形で関連していると感じます。これは、これら2つを一緒に見ることがよくあるためです。もしそうなら、どのくらい正確に?なぜそれらは関連している必要がありますか?

マルチスレッドの内部がどのように機能するのか、そしてメモリモデルが一般的に何を意味するのかわからないので、これらの概念を理解するのを手伝ってください。:-)

7 answers

2293
Nemo 2011-06-12 14:23.

まず、あなたは言語弁護士のように考えることを学ぶ必要があります。

C ++仕様は、特定のコンパイラ、オペレーティングシステム、またはCPUを参照していません。これは、実際のシステムを一般化した抽象マシンを参照しています。言語弁護士の世界では、プログラマーの仕事は抽象マシンのコードを書くことです。コンパイラの仕事は、具体的なマシンでそのコードを実現することです。仕様に厳密にコーディングすることで、現在または50年後を問わず、準拠したC ++コンパイラを備えたシステムでコードを変更せずにコンパイルおよび実行できるようになります。

C ++ 98 / C ++ 03仕様の抽象マシンは、基本的にシングルスレッドです。したがって、仕様に関して「完全に移植可能な」マルチスレッドC ++コードを作成することはできません。この仕様では、メモリのロードとストアのアトミック性や、ロードとストアが発生する可能性のある順序については何も述べられていません。ミューテックスなどは気にしないでください。

もちろん、実際には、pthreadやWindowsなどの特定の具体的なシステム用にマルチスレッドコードを記述できます。ただし、C ++ 98 / C ++ 03のマルチスレッドコードを作成する標準的な方法はありません。

C ++ 11の抽象マシンは、設計によりマルチスレッド化されています。また、明確に定義されたメモリモデルもあります。つまり、メモリへのアクセスに関して、コンパイラが実行できることと実行できないことを示しています。

次の例を考えてみましょう。ここでは、グローバル変数のペアが2つのスレッドによって同時にアクセスされます。

           Global
           int x, y;

Thread 1            Thread 2
x = 17;             cout << y << " ";
y = 37;             cout << x << endl;

スレッド2の出力は何でしょうか?

C ++ 98 / C ++ 03では、これは未定義の振る舞いでもありません。標準は「スレッド」と呼ばれるものを考慮していないため、質問自体は無意味です。

C ++ 11では、ロードとストアは一般にアトミックである必要がないため、結果は未定義の動作になります。これはあまり改善されていないように見えるかもしれません...そしてそれ自体ではそうではありません。

しかし、C ++ 11では、次のように書くことができます。

           Global
           atomic<int> x, y;

Thread 1                 Thread 2
x.store(17);             cout << y.load() << " ";
y.store(37);             cout << x.load() << endl;

今、物事ははるかに興味深いものになります。まず、ここでの動作を定義します。スレッド2は0 037 17(スレッド1の前に実行される場合)、(スレッド1の後に実行される場合)、または0 17(スレッド1がxに割り当てられた後、yに割り当てられる前に実行される場合)を出力できるようになりました。

37 0C ++ 11のアトミックロード/ストアのデフォルトモードは逐次一貫性を強制することであるため、印刷できないのはです。つまり、すべてのロードとストアは、各スレッド内で記述した順序で発生したかのように「あたかも」発生する必要がありますが、スレッド間の操作は、システムが好きなようにインターリーブできます。したがって、アトミックのデフォルトの動作は、ロードとストアの原子性順序の両方を提供します。

現在、最新のCPUでは、逐次一貫性の確保にコストがかかる可能性があります。特に、コンパイラは、ここでのすべてのアクセスの間に本格的なメモリバリアを放出する可能性があります。ただし、アルゴリズムが異常なロードとストアを許容できる場合は、つまり、原子性は必要だが順序付けは必要ない場合。つまり、37 0このプログラムからの出力として許容できる場合は、次のように記述できます。

           Global
           atomic<int> x, y;

Thread 1                            Thread 2
x.store(17,memory_order_relaxed);   cout << y.load(memory_order_relaxed) << " ";
y.store(37,memory_order_relaxed);   cout << x.load(memory_order_relaxed) << endl;

CPUが最新であるほど、前の例よりも高速になる可能性が高くなります。

最後に、特定のロードとストアを順番に保持する必要がある場合は、次のように記述できます。

           Global
           atomic<int> x, y;

Thread 1                            Thread 2
x.store(17,memory_order_release);   cout << y.load(memory_order_acquire) << " ";
y.store(37,memory_order_release);   cout << x.load(memory_order_acquire) << endl;

これにより、順序付けられたロードとストアに戻る37 0ことができるため、出力は不可能になりますが、最小限のオーバーヘッドで実行できます。(この些細な例では、結果は本格的な逐次一貫性と同じです。より大きなプログラムでは、そうではありません。)

もちろん、表示したい出力が0 0または37 17だけの場合は、元のコードをミューテックスでラップするだけです。しかし、これまで読んだことがあれば、それがどのように機能するかをすでに知っていると思います。この答えは、私が意図したよりもすでに長くなっています:-)。

つまり、収益です。ミューテックスは素晴らしく、C ++ 11はそれらを標準化します。ただし、パフォーマンス上の理由から、低レベルのプリミティブ(たとえば、従来のダブルチェックロックパターン)が必要な場合があります。新しい標準は、ミューテックスや条件変数などの高レベルのガジェットを提供し、アトミックタイプやさまざまな種類のメモリバリアなどの低レベルのガジェットも提供します。これで、完全に標準で指定された言語内で洗練された高性能の並行ルーチンを記述でき、コードが現在のシステムと将来のシステムの両方で変更されずにコンパイルおよび実行されることを確信できます。

率直に言って、あなたが専門家であり、深刻な低レベルのコードに取り組んでいない限り、おそらくミューテックスと条件変数に固執する必要があります。それが私がやろうとしていることです。

この内容の詳細については、このブログ投稿を参照してください。

356
Ahmed Nassar 2013-08-30 10:42.

メモリ整合性モデル(または略してメモリモデル)を理解するための例えを示します。これは、レスリー・ランポートの独創的な論文「分散システムにおける時間、時計、およびイベントの順序付け」に触発されています。類推は適切であり、基本的な意味がありますが、多くの人にとってはやり過ぎかもしれません。しかし、それが記憶の一貫性モデルについての推論を容易にする精神的なイメージ(絵の表現)を提供することを願っています。

横軸がアドレス空間を表し(つまり、各メモリ位置がその軸上の点で表される)、縦軸が時間を表す時空間図で、すべてのメモリ位置の履歴を表示してみましょう(これから、一般に、時間の普遍的な概念はありません)。したがって、各メモリ位置に保持されている値の履歴は、そのメモリアドレスの垂直列で表されます。それぞれの値の変更は、スレッドの1つがその場所に新しい値を書き込んでいるためです。メモリイメージは、我々は観測可能なすべてのメモリ位置の値の集計/組み合わせを意味します特定の時間にすることにより、特定のスレッドを

「メモリの一貫性とキャッシュの一貫性に関する入門書」からの引用

直感的な(そして最も制限的な)メモリモデルは逐次一貫性(SC)であり、マルチスレッド実行は、スレッドがシングルコアプロセッサで時分割多重化されているかのように、各構成スレッドの順次実行のインターリーブのように見えます。

そのグローバルメモリの順序は、プログラムの実行ごとに異なる可能性があり、事前にわからない場合があります。SCの特徴は、同時性の平面(つまり、メモリイメージ)を表すアドレス-時空間図の水平スライスのセットです。特定のプレーンでは、そのすべてのイベント(またはメモリ値)は同時に発生します。絶対時間の概念があり、すべてのスレッドがどのメモリ値が同時であるかについて合意します。SCでは、常に、すべてのスレッドで共有されるメモリイメージは1つだけです。つまり、すべての時点で、すべてのプロセッサがメモリイメージ(つまり、メモリの総コンテンツ)に同意します。これは、すべてのスレッドがすべてのメモリ位置に対して同じ値のシーケンスを表示することを意味するだけでなく、すべてのプロセッサがすべての変数の値の同じ組み合わせを監視することも意味します。これは、(すべてのメモリ位置での)すべてのメモリ操作がすべてのスレッドによって同じ全順序で監視されると言うのと同じです。

緩和されたメモリモデルでは、各スレッドは独自の方法でアドレス時空間をスライスします。唯一の制限は、すべてのスレッドがすべての個々のメモリ位置の履歴に同意する必要があるため、各スレッドのスライスが互いに交差しないことです(もちろん、異なるスレッドのスライスは互いに交差する可能性があり、交差する可能性があります)。それをスライスする普遍的な方法はありません(アドレス-時空の特権的な葉はありません)。スライスは平面(または線形)である必要はありません。それらは湾曲する可能性があり、これにより、別のスレッドによって書き込まれた値が書き込まれた順序から外れてスレッドが読み取られる可能性があります。特定のスレッドで表示すると、異なるメモリ位置の履歴が相互に任意にスライド(または引き伸ばされる)する可能性があります。。各スレッドは、どのイベント(または同等にメモリ値)が同時に発生するかについて異なる意味を持ちます。あるスレッドと同時に発生する一連のイベント(またはメモリ値)は、別のスレッドと同時に発生しません。したがって、緩和されたメモリモデルでは、すべてのスレッドが各メモリ位置について同じ履歴(つまり、値のシーケンス)を引き続き監視します。ただし、異なるメモリイメージ(つまり、すべてのメモリ位置の値の組み合わせ)を観察する場合があります。2つの異なるメモリ位置が同じスレッドによって順番に書き込まれる場合でも、新しく書き込まれた2つの値は、他のスレッドによって異なる順序で監視される場合があります。

[ウィキペディアからの写真]

アインシュタインの特殊相対性理論に精通している読者は、私がほのめかしていることに気付くでしょう。ミンコフスキーの言葉をメモリモデルの領域に翻訳する:アドレス空間と時間はアドレス-時空の影です。この場合、各オブザーバー(つまり、スレッド)は、イベントのシャドウ(つまり、メモリストア/ロード)を自分の世界線(つまり、時間軸)と自分の同時性平面(アドレス空間軸)に投影します。 。C ++ 11メモリモデルのスレッドは、特殊相対性理論で相互に相対的に移動しているオブザーバーに対応します。逐次一貫性は、ガリラヤの時空に対応します(つまり、すべてのオブザーバーは、イベントの1つの絶対的な順序とグローバルな同時性の感覚に同意します)。

メモリモデルと特殊相対性理論の類似性は、両方が部分的に順序付けられたイベントのセットを定義するという事実に由来します。これは、しばしば因果集合と呼ばれます。一部のイベント(つまり、メモリストア)は、他のイベントに影響を与える可能性があります(ただし、影響を受けません)。C ++ 11スレッド(または物理学のオブザーバー)は、イベントのチェーン(つまり、完全に順序付けられたセット)にすぎません(たとえば、メモリのロードと、場合によっては異なるアドレスへの格納)。

相対性理論では、すべてのオブザーバーが同意する唯一の時間的順序は「時空」イベント(つまり、粒子が遅くなることによって原則的に接続可能なイベント)間の順序であるため、一部の順序は半順序イベントの一見混沌とした図に復元されます真空中の光速よりも)。時空に関連するイベントのみが常に順序付けられます。物理学の時間、クレイグ・カレンダー。

C ++ 11メモリモデルでは、同様のメカニズム(取得-解放整合性モデル)を使用して、これらのローカル因果関係を確立します。

メモリの一貫性の定義とSCを放棄する動機を提供するために、「メモリの一貫性とキャッシュの一貫性に関する入門書」から引用します。

共有メモリマシンの場合、メモリ整合性モデルは、そのメモリシステムのアーキテクチャ上目に見える動作を定義します。シングルプロセッサコアの正当性基準は、「1つの正しい結果」と「多くの誤った選択肢」の間で動作を分割します。これは、プロセッサのアーキテクチャが、スレッドの実行により、順序が正しくないコアであっても、特定の入力状態を単一の明確に定義された出力状態に変換することを義務付けているためです。ただし、共有メモリの整合性モデルは、複数のスレッドのロードとストアに関係し、通常、多くの(より多くの)誤ったスレッドを許可せずに、多くの正しい実行を許可します。複数の正しい実行の可能性は、ISAが複数のスレッドを同時に実行できるようにするためであり、多くの場合、異なるスレッドからの命令が合法的にインターリーブされる可能性があります。

緩和された、または弱いメモリ整合性モデルは、強いモデルのほとんどのメモリ順序が不要であるという事実によって動機付けられています。スレッドが10個のデータ項目を更新してから同期フラグを更新する場合、プログラマーは通常、データ項目が相互に順番に更新されるかどうかを気にせず、フラグが更新される前にすべてのデータ項目が更新されることだけを気にします(通常はFENCE命令を使用して実装されます) )。緩和されたモデルは、この増加した順序付けの柔軟性をキャプチャし、SCのより高いパフォーマンスと正確さの両方を得るためにプログラマーが「必要とする」順序のみを保持しようとします。たとえば、特定のアーキテクチャでは、FIFO書き込みバッファは、結果をキャッシュに書き込む前に、コミットされた(リタイアされた)ストアの結果を保持するために各コアによって使用されます。この最適化はパフォーマンスを向上させますが、SCに違反します。書き込みバッファは、ストアミスの処理の待ち時間を隠します。店舗は一般的であるため、ほとんどの店舗でストールを回避できることは重要なメリットです。シングルコアプロセッサの場合、Aへの1つ以上のストアが書き込みバッファにある場合でも、アドレスAへのロードが最新のストアの値をAに返すようにすることで、書き込みバッファをアーキテクチャ的に見えなくすることができます。これは通常、Aへの最新のストアの値をAからのロードにバイパスすることによって行われます。「最新」はプログラムの順序によって決定されます。または、Aへのストアが書き込みバッファにある場合はAのロードをストールします。 。複数のコアを使用する場合、それぞれに独自のバイパス書き込みバッファがあります。書き込みバッファがない場合、ハードウェアはSCですが、書き込みバッファがある場合はそうではなく、マルチコアプロセッサでアーキテクチャ的に書き込みバッファを表示できます。

コアにFIFO以外の書き込みバッファーがあり、ストアが入力された順序とは異なる順序で出発できる場合、ストアストアの並べ替えが発生する可能性があります。これは、2番目のストアがヒットしているときに最初のストアがキャッシュでミスした場合、または2番目のストアが以前のストアと合体できる場合(つまり、最初のストアの前)に発生する可能性があります。ロードロードの並べ替えは、プログラムの順序から外れた命令を実行する動的にスケジュールされたコアでも発生する可能性があります。これは、別のコアでストアを並べ替えるのと同じように動作します(2つのスレッド間でインターリーブする例を思い付くことができますか?)。以前のロードを後のストアに並べ替える(ロードストアの並べ替え)と、値を保護するロックを解除した後に値をロードするなど、多くの誤った動作が発生する可能性があります(ストアがロック解除操作の場合)。プログラムの順序ですべての命令を実行するコアを使用している場合でも、一般的に実装されているFIFO書き込みバッファーでのローカルバイパスが原因で、ストアロードの並べ替えが発生する可能性があることに注意してください。

キャッシュの一貫性とメモリの一貫性が混同されることがあるため、次の引用も参考にしてください。

一貫性とは異なり、キャッシュコヒーレンスはソフトウェアからは見えず、必要でもありません。Coherenceは、共有メモリシステムのキャッシュを、シングルコアシステムのキャッシュと同じように機能的に見えないようにすることを目指しています。正しいコヒーレンスにより、プログラマーは、ロードとストアの結果を分析することによって、システムにキャッシュがあるかどうか、どこにあるかを判別できなくなります。これは、正しいコヒーレンスにより、キャッシュが新しいまたは異なる機能動作を有効にしないことが保証されるためです(プログラマーは、タイミング情報を使用して、可能性のあるキャッシュ構造を推測できる場合があります)。キャッシュコヒーレンスプロトコルの主な目的は、すべてのメモリ位置に対してシングルライター-マルチリーダー(SWMR)を不変に維持することです。コヒーレンスと整合性の重要な違いは、コヒーレンスはメモリ位置ごとに指定されるのに対し、整合性はすべてのメモリ位置に関して指定されることです。

私たちの心の絵を続けると、SWMR不変量は、任意の1つの場所に最大で1つの粒子が存在するという物理的要件に対応しますが、任意の場所のオブザーバーの数に制限はありません。

122
eran 2013-12-21 03:22.

これは現在、複数年前の質問ですが、非常に人気があるため、C ++ 11メモリモデルについて学習するための素晴らしいリソースに言及する価値があります。これをさらに完全な答えにするために彼の話を要約しても意味がありませんが、これが実際に標準を書いた人であることを考えると、話を見る価値があると思います。

Herb Sutterは、Channel9サイト(パート1とパート2)で入手できる「atomic <> Weapons」というタイトルのC ++ 11メモリモデルについて3時間の長い話をしています。講演はかなり技術的で、次のトピックをカバーしています。

  1. 最適化、人種、およびメモリモデル
  2. 注文–内容:取得してリリース
  3. 順序付け–方法:ミューテックス、アトミック、および/またはフェンス
  4. コンパイラとハードウェアに関するその他の制限
  5. コードの生成とパフォーマンス:x86 / x64、IA64、POWER、ARM
  6. リラックスした原子

話はAPIについて詳しく説明していませんが、推論、背景、内部および舞台裏について詳しく説明しています(POWERとARMが同期ロードを効率的にサポートしていないという理由だけで、リラックスしたセマンティクスが標準に追加されたことをご存知ですか?)。

77
Puppy 2011-06-12 13:42.

これは、標準がマルチスレッドを定義するようになり、複数のスレッドのコンテキストで何が起こるかを定義することを意味します。もちろん、人々はさまざまな実装を使用していましたがstd::string、それは、私たち全員がホームロールstringクラスを使用できるのに、なぜ必要なのかを尋ねるようなものです。

POSIXスレッドまたはWindowsスレッドについて話している場合、これは、同時に実行するハードウェア関数であるため、実際にはx86スレッドについて話しているのと同じように少し幻想です。C ++ 0xメモリモデルは、x86、ARM、MIPS、またはその他の考えられるものに関係なく、保証を提供します。

58
ritesh 2011-07-26 18:27.

メモリモデルを指定していない言語の場合、プロセッサアーキテクチャで指定されている言語メモリモデルのコードを記述しています。プロセッサは、パフォーマンスのためにメモリアクセスを並べ替えることを選択できます。したがって、プログラムにデータ競合がある場合(データ競合とは、複数のコア/ハイパースレッドが同じメモリに同時にアクセスできる場合です)、プロセッサのメモリモデルに依存しているため、プログラムはクロスプラットフォームではありません。プロセッサがメモリアクセスを並べ替える方法については、IntelまたはAMDのソフトウェアマニュアルを参照してください。

非常に重要なことに、ロック(およびロックを使用した同時実行セマンティクス)は通常、クロスプラットフォームの方法で実装されます...したがって、データ競合のないマルチスレッドプログラムで標準ロックを使用している場合は、クロスプラットフォームのメモリモデルについて心配する必要はありません。

興味深いことに、C ++用のMicrosoftコンパイラは、C ++のメモリモデルの欠如に対処するためのC ++拡張機能であるvolatileのセマンティクスを取得/リリースしています。 http://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx。ただし、Windowsがx86 / x64でのみ実行されることを考えると、それほど多くはありません(IntelおよびAMDメモリモデルを使用すると、言語で取得/解放セマンティクスを簡単かつ効率的に実装できます)。

28
ninjalj 2011-06-12 13:49.

ミューテックスを使用してすべてのデータを保護する場合は、心配する必要はありません。ミューテックスは常に十分な順序と可視性の保証を提供してきました。

ここで、アトミックまたはロックフリーアルゴリズムを使用した場合は、メモリモデルについて考える必要があります。メモリモデルは、アトミックが順序付けと可視性の保証を提供する時期を正確に記述し、手作業でコード化された保証のためのポータブルフェンスを提供します。

以前は、アトミックはコンパイラ組み込み関数またはより高いレベルのライブラリを使用して実行されていました。フェンスは、CPU固有の命令(メモリバリア)を使用して実行されます。

3
Mike Spear 2019-12-20 17:56.

上記の回答は、C ++メモリモデルの最も基本的な側面を示しています。実際には、std::atomic<>少なくともプログラマーが過度に最適化するまで(たとえば、あまりにも多くのことをリラックスしようとすることによって)、「ただ働く」のほとんどの使用法。

間違いがまだよくある場所が1つあります。それは、シーケンスロックです。課題についての優れた読みやすい議論がありますhttps://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf。リーダーがロックワードへの書き込みを回避するため、シーケンスロックは魅力的です。次のコードは、上記のテクニカルレポートの図1に基づいており、C ++でシーケンスロックを実装する際の課題を強調しています。

atomic<uint64_t> seq; // seqlock representation
int data1, data2;     // this data will be protected by seq

T reader() {
    int r1, r2;
    unsigned seq0, seq1;
    while (true) {
        seq0 = seq;
        r1 = data1; // INCORRECT! Data Race!
        r2 = data2; // INCORRECT!
        seq1 = seq;

        // if the lock didn't change while I was reading, and
        // the lock wasn't held while I was reading, then my
        // reads should be valid
        if (seq0 == seq1 && !(seq0 & 1))
            break;
    }
    use(r1, r2);
}

void writer(int new_data1, int new_data2) {
    unsigned seq0 = seq;
    while (true) {
        if ((!(seq0 & 1)) && seq.compare_exchange_weak(seq0, seq0 + 1))
            break; // atomically moving the lock from even to odd is an acquire
    }
    data1 = new_data1;
    data2 = new_data2;
    seq = seq0 + 2; // release the lock by increasing its value to even
}

最初は継ぎ目があるのと同じくらい直感的ではなく、data1であるdata2必要がありますatomic<>。それらがアトミックでない場合は、reader()(でwriter())書き込まれるのとまったく同時に(で)読み取ることができます。C ++メモリモデルによると、実際にデータを使用したことがない場合でもreader()、これは競争です。さらに、それらがアトミックでない場合、コンパイラーは各値の最初の読み取りをレジスターにキャッシュできます。明らかに、あなたはそれを望まないでしょう...あなたはのwhileループの各反復で再読み込みしたいですreader()

また、それらを作成しatomic<>てにアクセスするだけでは不十分memory_order_relaxedです。これは、seq(in reader())の読み取りには取得セマンティクスしかないためです。簡単に言うと、XとYがメモリアクセスであり、XがYに先行し、Xが取得または解放ではなく、Yが取得である場合、コンパイラはXの前にYを並べ替えることができます。Yがseqの2番目の読み取りであり、Xデータの読み取りであった場合、そのような並べ替えはロックの実装を壊します。

この論文はいくつかの解決策を示しています。今日最高のパフォーマンスを発揮するのは、おそらくseqlockの2回目の読み取りのatomic_thread_fencewithを使用するものです。論文では、それは図6です。これまで読んだ人は誰でも本当に論文を読むべきなので、ここではコードを再現していません。この投稿よりも正確で完全です。memory_order_relaxed

最後の問題は、data変数をアトミックにするのは不自然かもしれないということです。コードに含めることができない場合は、非常に注意する必要があります。非アトミックからアトミックへのキャストは、プリミティブ型に対してのみ有効であるためです。C ++ 20はatomic_ref<>、この問題の解決を容易にするを追加することになっています。

要約すると、C ++メモリモデルを理解していると思っていても、独自のシーケンスロックをロールする前に十分に注意する必要があります。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

グッドジョブ、ESPN

グッドジョブ、ESPN

今日のホワイトハウスの記者会見で、報道官のサラ・ハッカビー・サンダースは、スポーツセンターのホストであるイェメル・ヒルのドナルド・トランプに関する最近のツイートについてコメントするよう求められ、大統領と彼の政策を白人至上主義者として説明した。ヒルは彼女のつぶやきのためにESPNによって公に叱責されました。

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

基本的に頭のあらゆる部分から髪の毛を整えたり、ブロードライしたり、まっすぐにしたり、脱毛したりする必要がある場合は、このレミントンゴールドボックスが最適です。今日だけ、Amazonは、すでに人気のあるShortcut Pro Self-HaircutKitやPearlPro Ceramic Flat Ironのように、グルーミングをはるかに簡単にするヘアツールをマークダウンしています。

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

トゥパックシャクール(ティムモーゼンフェルダー/ゲッティイメージズ); マヤアンジェロウ(マーティンゴッドウィン/ゲッティイメージズ)移動、テイラースウィフト。ケンドールとカイリーは、必要な数の座席を持っています。

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

写真:Tesla Motorsフロリダに住んでいて、Tesla Model S、Model X 60、またはModel 60Dを使用している場合、車の自律性は50 km(約30マイル)高くなります。これは失敗ではなく、ハリケーンイルマによる避難作業を容易にするために会社自身が命じた自治権の一時的な延長です。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language