問題タブ [memory-model]

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.

0 投票する
2 に答える
2509 参照

c++ - C ++ 0xのフェンス、一般的にアトミックまたはメモリのみを保証

C ++ 0xドラフトには、CPU /チップレベルのフェンスの概念とは非常に異なるように見えるフェンスの概念があります。つまり、Linuxカーネルの人がフェンスに期待することを言います。問題は、ドラフトが本当に極端に制限されたモデルを暗示しているのか、それとも言い回しが貧弱で実際に真のフェンスを暗示しているのかということです。

たとえば、29.8フェンスでは、次のように記述されます。

リリースフェンスAは、AがXの前にシーケンスされ、XがMを変更し、YがBの前にシーケンスされ、Yが値を読み取るように、両方が何らかのアトミックオブジェクトMで動作するアトミック操作XおよびYが存在する場合、取得フェンスBと同期します。 Xによって書き込まれた値、または仮想のリリースシーケンスXのいずれかのサイドエフェクトによって書き込まれた値は、リリース操作の場合に先頭になります。

これらの用語atomic operationsとを使用しatomic objectます。ドラフトで定義されているそのような不可分操作とメソッドがありますが、それはそれらだけを意味するのでしょうか?リリースフェンスはストアフェンスのように聞こえます。フェンスの前にすべてのデータの書き込みを保証しないストアフェンスはほとんど役に立たない。ロード(取得)フェンスとフルフェンスについても同様です。

それで、C ++ 0xの適切なフェンスと言い回しのフェンス/バリーは非常に貧弱ですか、それとも説明されているように非常に制限されている/役に立たないのですか?


C ++に関して、私がこの既存のコードを持っているとしましょう(GCCで__sync_synchronizeを使用する代わりに、フェンスが現在高レベルの構造として利用可能であると仮定します):

a、b、cが、プラットフォーム上にアトミックコピーを持つサイズであると想定します。上記は、cこれまでにのみ割り当てられることを意味します9a==5スレッドBがいつ表示されるかは関係ありませんが、スレッドBが表示されるときにも表示されることに注意してくださいb==9

同じ関係を保証するC++0xのコードは何ですか?


答え:私の選んだ答えとすべてのコメントを読むと、状況の要点がわかります。C ++ 0xは、フェンスでアトミックを使用するように強制しているように見えますが、通常のハードウェアフェンスにはこの要件がありません。多くの場合、とがである限り、これを使用して並行アルゴリズムを置き換えることができsizeof(atomic<T>) == sizeof(T)ますatomic<T>.is_lock_free() == true

残念ながら、それはis_lock_freeconstexprではありません。これにより、で使用できるようになりますstatic_assert。ロックの使用に退化することは一般的に悪い考えです。ミューテックスをatomic<T>使用するアトミックアルゴリズムは、ミューテックスで設計されたアルゴリズムと比較して、ひどい競合の問題を抱えています。

0 投票する
3 に答える
552 参照

java - Java メモリ モデルに関する質問

数日前に、「揮発性」というキーワードをどのように使用するかを尋ねる質問を投げかけ、答えを得ました。ここで、私を助けてくれた人々に改めて感謝したいと思います。しかし、JMM について新たな疑問が頭に浮かびました。それは現在、メイン メモリとスレッド独自の個別のキャッシュ メモリがあることを知っています (それらには、より専門的な用語があるかもしれません)。今、スレッド キャッシュ メモリに格納されているものを知りたいです。共有オブジェクト参照のコピー (オブジェクト アドレスのコピー) または共有オブジェクトのコピー? たとえば、オブジェクト B b = new B(); を宣言します。b が 2 つのスレッドからアクセスできる場合、b がスレッドによってアクセスされるとき、オブジェクト参照b はコピーされてスレッド独自のキャッシュ メモリに格納されますか、それともb が指すオブジェクトがコピーされてスレッド独自のキャッシュ メモリに格納されますか? ありがとう。

0 投票する
3 に答える
6411 参照

c - C の文字列定数と文字配列

重複の可能性:
C の char s[] と char *s の違いは何ですか?

何かを修正しようとするのではなく、一般的な質問のほうが多いので、私は C プログラミング言語の本を読んでいます。

1 つは char 配列であり、もう 1 つは文字列定数へのポインターです。彼らは char 配列を変更することは許容できると言いますが、未定義の動作を引き起こすため、文字列定数を変更しないでください。私の質問は次のとおりです。文字列定数は、char配列と同じようにメモリに格納されていませんか? なぜ私はそれを次のように変更できますか

ご想像のとおり、「これは文字列定数です」と出力されます。文字列定数は実行時に変更されるべきではないので、それがどのように理にかなっているのか理解できます。なぜなら、コードに取り組んでいる他の人/自分自身が、その値が変更されることを期待していないことを混乱させる可能性があるからです。 、トリガーされる可能性のある未定義の動作は何ですか?また、char配列がトリガーしない場合に、どのように機械的に逆火する可能性がありますか? 文字列定数がメモリ内でどのように機能し、コンパイラによってどのように認識されるかについて、何かが欠けているのではないかと思っています。

0 投票する
1 に答える
378 参照

c++ - 「-mcmodel=medium」GCC コンパイラ設定に相当する Qt4 Creator/QMAKE

Qt Creator を使用して、Linux でかなりメモリを集中的に使用する C++ アプリケーションの GUI を作成しています。アプリケーションを適切に実行するには、コンパイル中に-mcmodel=mediumコンパイラ フラグを設定する必要があります。そうしないと、実行中にアプリケーションが突然クラッシュします (それなしで Qt でコンパイルしようとすると、予期したとおりにクラッシュします)。これを直接処理するために.proファイルにGCC フラグを設定するにはどうすればよいですか? または、このメモリ モデル フラグ設定に相当する Qt がありますか?

注: QMAKE_CXXFLAGS += -mcmodel=medium を試しましたが、うまくいかないようです...

訂正: QMAKE_CXXFLAGS メソッドは機能しているようです。返されたエラーは、実際にはハードウェア メモリ バス エラーでした。

0 投票する
2 に答える
489 参照

java - スレッドの作成および結合時の副作用の可視性

同期ブロックや揮発性変数がない場合、あるスレッドによって実行された書き込みが別のスレッドから見えるのはいつですか? 簡単なクイックソートの例を次に示します。

(簡単にするために、2 つの「ワーカー スレッド」は追加のスレッドを生成しないと仮定します。)

2 つのスレッドを結合すると、現在のスレッドがすべての副作用を確認できることが保証されますか?


関連して、最初のパーティショニングのにスレッドを作成するとどうなりますか?

2 つのスレッドは、によって引き起こされる副作用を確認できpartitionForTheFirstTime()ますか? つまり、スレッドを作成すると、事前発生の関係が発生しますか、それともスレッドを開始しますか?

0 投票する
8 に答える
265196 参照

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

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

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

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

「標準に含まれるさまざまなコア間で[コード]を分割することについて話しているときは、メモリモデルについて話している。人々がコードで行う次の仮定を破ることなく、それを最適化する」とサッター氏は述べた。

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

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

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

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

0 投票する
2 に答える
9763 参照

c++ - [[carries_dependency]]属性はどういう意味ですか?

誰かがそれを単なる人間が理解できる言語で説明できますか?

0 投票する
2 に答える
1261 参照

c# - release/acquire セマンティクスを持つ volatile

Java 5 以降、volatileキーワードにはリリース/取得セマンティクスがあり、副作用を他のスレッドから見えるようにします (非揮発性変数への代入を含む!)。たとえば、次の 2 つの変数を使用します。

iは通常の非揮発性変数であることに注意してください。次のステートメントを実行するスレッド 1 を想像してください。

その後、スレッド 2 は次のステートメントを実行します。

Java メモリ モデルによると、vスレッド 1 での書き込みとそれに続くスレッド 2 での読み取りによりv、スレッド 2 はiスレッド 1 で実行された書き込みを認識できるため、値 42 が出力されます。

私の質問はvolatile、C# で同じリリース/取得セマンティクスを持っていますか?

0 投票する
1 に答える
762 参照

java - JVM/JITによるフェンス命令の挿入

JavaメモリモデルはDRF保証(データレースの自由)を提供します。つまり、Javaのリラックスしたメモリモデルで実行された場合、データレースのないプログラムは、逐次一貫性のある実行と同じ動作をします。私は次の質問があります:a)際どいプログラムが与えられた場合、コンパイラは(非常に具体的には任意のjvm実装)遅延セット分析/スレッドエスケープ分析などを実行して、レースにするために挿入する必要のあるフェンス命令を見つけます-自由?それとも、JITはどこで実行されるかに基づいてそれを行いませんか?

b)コンパイラがそれを行う場合(この場合はjvm)、コンパイラはとにかくそれをレースフリープログラムに変換するので、なぜ私たちは際どいプログラムを書くことができないのですか?そして、コンパイラーがそれを行う方法(フェンスの挿入によってレースフリーにする)の場合、Javaでの同時データ構造の実装のように、(意図的に)際どいプログラムをどのように書くことができますか?

c)または、jvm自体がレーシーをレースフリープログラムに変換しないという3番目の可能性がありますが、それを実行できる他の分析が存在します。本当ですか?

0 投票する
3 に答える
3773 参照

c++ - `std::kill_dependency` は何をしますか? なぜそれを使いたいのですか?

私は新しいC++ 11メモリモデルについて読んでいて、std::kill_dependency関数に出くわしました(§29.3/14-15)。なぜそれを使いたいのか理解に苦しむ。

N2664 提案で例を見つけましたが、あまり役に立ちませんでした。

なしでコードを表示することから始めますstd::kill_dependency。ここで、最初の行は依存関係を 2 番目の行に運び、依存関係をインデックス付け操作に運び、次に依存関係をdo_something_with関数に運びます。

std::kill_dependency2行目と索引付けの間の依存関係を壊すために使用する別の例があります。

私が知る限り、これは、インデックス作成と への呼び出しdo_something_withが、2 行目の前に順序付けられた依存関係ではないことを意味します。N2664によると:

これにより、コンパイラはdo_something_with、たとえば、 の値を予測する投機的最適化を実行することにより、への呼び出しを並べ替えることができますa[r2]

値を呼び出すにdo_something_withは、値a[r2]が必要です。仮に、配列がゼロで埋められていることをコンパイラが「知っている」場合、その呼び出しを最適化do_something_with(0);し、他の 2 つの命令に対してこの呼び出しを必要に応じて並べ替えることができます。次のいずれかを生成できます。

私の理解は正しいですか?

他の方法で別のスレッドと同期する場合、呼び出しとこの別のスレッドdo_something_withの順序に関して、これはどういう意味ですか?x.load

私の理解が正しいと仮定すると、私を悩ませることがまだ 1 つあります。コードを書いているとき、どのような理由で依存関係を破棄することを選択するのでしょうか?