タスク並列ライブラリを使い始めたばかりで、興味深い問題に遭遇しました。私は何が起こっているのかについての一般的な考えを持っていますが、何が起こっているのかを理解するのを助けるために私より有能な人々からのコメントを聞きたいです。やや長いコードについてお詫びします。
ランダムウォークの非並列シミュレーションから始めました。
var random = new Random();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var simulations = new List<int>();
for (var run = 0; run < 20; run++)
{
var position = 0;
for (var step = 0; step < 10000000; step++)
{
if (random.Next(0, 2) == 0)
{
position--;
}
else
{
position++;
}
}
Console.WriteLine(string.Format("Terminated run {0} at position {1}.", run, position));
simulations.Add(position);
}
Console.WriteLine(string.Format("Average position: {0} .", simulations.Average()));
stopwatch.Stop();
Console.WriteLine(string.Format("Time elapsed: {0}", stopwatch.ElapsedMilliseconds));
Console.ReadLine();
次に、並列ループでの最初の試みを書きました。
var localRandom = new Random();
stopwatch.Reset();
stopwatch.Start();
var parallelSimulations = new List<int>();
Parallel.For(0, 20, run =>
{
var position = 0;
for (var step = 0; step < 10000000; step++)
{
if (localRandom.Next(0, 2) == 0)
{
position--;
}
else
{
position++;
}
}
Console.WriteLine(string.Format("Terminated run {0} at position {1}.", run, position));
parallelSimulations.Add(position);
});
Console.WriteLine(string.Format("Average position: {0} .", parallelSimulations.Average()));
stopwatch.Stop();
Console.WriteLine(string.Format("Time elapsed: {0}", stopwatch.ElapsedMilliseconds));
Console.ReadLine();
1コアのみを使用するように設定された仮想マシンで実行した場合、同様の期間が観察されましたが、実行は順番に処理されなくなりました。当然のことです。
デュアルコアマシンで実行したとき、状況は奇妙になりました。時間の改善は見られず、実行ごとに非常に奇妙な結果が見られました。ほとんどの実行の結果は-1,000,000(または非常に近い)になります。これは、Random.Nextが常に0準を返していることを示しています。
ランダムを各ループにローカルにすると、すべてが正常に機能し、期待される期間の改善が得られます。
Parallel.For(0, 20, run =>
{
var localRandom = new Random();
var position = 0;
私の推測では、問題はRandomオブジェクトがループ間で共有されており、何らかの状態があるという事実に関係していると思います。「失敗した並列」バージョンで期間が改善されていないのは、ランダムへの呼び出しが並列で処理されないためだと思います(並列バージョンは両方のコアを使用しますが、元のバージョンは使用しません) 。私が実際に得られない部分は、シミュレーション結果がそれらが何であるかという理由です。
私が抱えているもう1つの懸念は、各ループにローカルなランダムインスタンスを使用すると、同じシードで始まる複数のループが発生する可能性があることです(複数のランドムを時間的に近すぎる場合に発生する問題で、結果として同一になります)シーケンス)。
何が起こっているのかについての洞察は私にとって非常に貴重です!