13

各スレッドがアレイの特定のサブセットに対してのみ読み取り/書き込みを行うことが保証されている場合、クリティカルセクションなどに頼ることなく、複数のスレッドが同じ(静的)アレイで動作できますか?

編集-これは、参照カウントされていないタイプの配列とそのレコード/パックレコードの特定の場合です。

はいの場合、注意点はありますか?

私の腸の感覚はイエスですが、私の腸は信頼できない情報源になることがあります。

4

2 に答える 2

9

仮定:

  1. 配列 (静的または動的) の単一のインスタンスがあり、かつ
  2. 配列の要素は純粋な値の型 (つまり、参照を含まない) であり、
  3. 各スレッドは互いに素な部分配列で動作し、
  4. スレッドが配列で動作している間、システム内の他のものは配列に書き込みません。

これらの条件は、データ構造とスレッド パターンによって満たされていると思われますが、すべてのアルゴリズムはスレッド セーフです。

于 2012-04-16T14:50:43.930 に答える
8

いいえ、状況によっては、これはスレッドセーフではありません。

少なくとも2つの理由があります。

1.静的アレイの内容によって異なります。

参照カウントされていないタイプ(などdouble, integer, bytes, shortstring)を使用する場合、ほとんどの場合(少なくともデータが読み取り/専用の場合)問題は発生しません。

ただし、参照カウント型(string, interface、、またはネストされた動的配列など)を使用する場合は、スレッドセーフに注意する必要があります。

あれは:

TMyType1: array[0..1] of integer; // thread-safe on reading
TMyType2: array[0..1] of string;  // may be confusing

追記string静的配列の一部のサブパーツ間で実際に共有されている場合は、参照カウントが混乱する可能性があります。それぞれを明示的に要求UniqueString()しない限り(クリティカルセクション内では、私は疑っています)。doubleまたはの配列の場合integer、この問題は発生しません。

2.アクセスの同時実行性に依存します

読み取りアクセスは、参照カウントタイプの場合でもスレッドセーフである必要がありますが、同時書き込みは混乱を招く可能性があります。のstring場合、特にマルチコアCPUで、ランダムなケースでGPFの問題が発生する可能性があります。

安全な実装には次のようなものがあります。

  • クリティカルセクション(オーバーヘッドを減らすために可能な限り小さい)または他の保護構造を使用します。
  • 確かに、コピーオンライトまたはコンテンツのスレッドごとのプライベートコピーを使用してください。
  • 最新の注意事項(安全性ではなくパフォーマンス):複数のCPU間でアレイを共有すると、CPU間のキャッシュ同期により、パフォーマンスが低下する可能性があります。分離されたアレイを使用すると、パフォーマンスが大幅に向上する場合があり、それらのL1キャッシングウィンドウがCPU間で共有されないようにします。

このような問題は、クライアント側ではデバッグの悪夢になる可能性があることに注意してください。マルチスレッドの同時実行の問題はランダムに発生する可能性があり、追跡が非常に困難です。明示的で実証済みのパフォーマンスの問題がない限り、安全であるほど良いです。

追記:doubleの静的配列の特定のケースでは、配列のサブ部分に1つのスレッドのみがアクセスするため、スレッドセーフです。ただし、静的配列の場合でも、すべての状況でスレッドの安全性に関する絶対的なルールはありません。いくつかの参照カウント型またはいくつかのポインターを使用するとすぐに、ランダムな問題が発生する可能性があります。

于 2012-04-16T14:09:14.207 に答える