2016-10-08 9 views
1

私は10件のスレッドと長さのVecを持っている100異なるスレッドが同じVecの異なるセクションに書き込むことはできますか?

スレッド1は、などの要素10-19、に取り組んでいる間、私は、要素0-9(例えば、それらを並べ替える)上のスレッド0仕事を持つことができますか?

これにはVec<Vec<>>を使用する必要がありますか? (私はむしろ避けたいのは、要素がもはやメモリ内で連続しないためです)

+0

インターネットで "rust vec thread"を検索すると、http://stackoverflow.com/q/28599334/155423になります。 http://stackoverflow.com/q/31644152/155423; http://stackoverflow.com/q/33818141/155423;その他多数。あなた自身の努力をして、質問をするときにその努力を示すようにしてください(http://meta.stackoverflow.com/q/261592/155423)。 – Shepmaster

+0

@Shepmasterありがとう – MaxB

答えて

9

はい、できます。あなたは変更可能なケースについて尋ねましたが、Vecが読み取り専用の場合(たとえば、削減の場合)、スレッドごとに必要な特定のスライスに不変の参照を安全に送ることができます。あなたはループ内で&my_vec[idx1..idx2]のようなものを単に使うことでこれを行うことができます。

借用トラッカーは、Vecの重複しない借用を許可するのに十分なほど精巧ではないため、変更可能なケースは少し厄介です。しかし、多くの方法があります。特に、split_at_mutを呼び出して、これらのサブスライスを取得することができます。はるかに簡単なのは、hereと書かれているchunks_mutイテレータです。 (不変の場合にはchunksの反復子がありますので、どちらの場合でも小さな変更を加えるだけです)。

chunkschunks_mut機能は、各チャンクのサイズ、ないチャンクの数を取ることに注意してください。しかし、一方を他方から引き出すことはかなり簡単です。

しかし、私は、変更可能なケースに注意してください。データを均等に分割すると、パフォーマンスが低下する可能性があります。その理由は、CPUが個々のアドレスで動作しないのに対し、64バイトのキャッシュラインとして知られているメモリブロックで動作するからです。複数のスレッドが1つのキャッシュライン上で動作する場合は、スレッド間の一貫性を保証するために、より低速なメモリを書き込んで読み込む必要があります。

残念ながら、安全なRustでは、Vecのバッファが開始する(バッファの開始がCPUキャッシュラインの途中に割り当てられている可能性があるため)キャッシュ行のどこにあるのかを簡単に判断できません。これを検出するためには、実際のポインタアドレスの下位バイトがつぶれていることがわかります。これを処理する最も簡単な方法は、使用したい各チャンクの間にナンセンスデータの64バイトのパッドを追加するだけです。したがって、たとえば、1024個の32ビット浮動小数点数と10個のスレッドを含むVecがある場合、ダミー値を持つ浮動小数点数を加算するだけです(32ビット= 4バイト、16 * 4 = 64 = 1キャッシュライン)。あなたの "本当の" 100個の浮動小数点数は計算中にダミーを無視します。

これは誤った共有と呼ばれ、他の方法でこの問題を解決する方法を学ぶことをおすすめします。

64バイトのラインサイズはx86アーキテクチャで保証されています。 ARM、PowerPC、MIPSなどでコンパイルしている場合は、この値は変わる可能性があります。

関連する問題