WindowsとLinuxのスレッド(またはファイバー)について、任意のプログラミング言語で一般的な質問があります。
「2番目のスレッドを待機」させて、すぐに実行に移し、プリエンプトされることなく、数ミリ秒の間小さなタスクを支援することは可能ですか?ミューテックスとスピンロックのない読みやすいコードを望んでいることを付け加えておきます。
従来のスレッドプールが小さなタスクでは機能しないことを示すために、C#でのマトリックス反転の問題を検討してください。IvanKuckirの行列クラスを使用しています。彼のInvert関数をコピーして、次のようにInvertParallelと呼びます。
public Matrix InvertParallel() // modified from Ivan's Invert(), see link above
{
if (L == null) MakeLU();
Matrix inv = new Matrix(rows, cols);
Parallel.ForEach<int>(Enumerable.Range(0, rows), rowID =>
{
Matrix Ei = Matrix.ZeroMatrix(rows, 1);
Ei[rowID, 0] = 1;
Matrix col = SolveWith(Ei);
inv.SetCol(col, rowID);
});
return inv;
}
次に、Invert関数とInvert_Parallel関数の両方を呼び出して、それにかかる時間を測定します。
static void Main()
{
Stopwatch sw = new Stopwatch(); sw.Start();
Matrix A = Matrix.IdentityMatrix(50, 50);
Matrix I1 = A.Invert();
long elapsed1 = sw.ElapsedMilliseconds;
Matrix I2 = A.InvertParallel();
long elapsed2 = sw.ElapsedMilliseconds - elapsed1;
Console.WriteLine("Matrix size=" + A.rows + ", Invert=" + elapsed1 + "ms, Invert_Parallel=" + elapsed2 + "ms");
}
かなり明白な結果は、小さなタスク(マトリックスサイズ50)の場合、スレッドプールからのタスクの起動はシングルスレッドの実行よりも遅いことを示しています。
Matrix size=50, Invert= 5ms, InvertParallel=21ms
Matrix size=100, Invert= 19ms, InvertParallel=24ms
Matrix size=200, Invert=137ms, InvertParallel=44ms
(お詫び-私は新しいポスターなので、以下のメモからすべてのリンクを削除する必要がありました)
PS関連のS/O記事:「2つのスレッドを同時に開始する方法」、「Linux-スレッドとプロセスのスケジューリングの優先順位」
PSはい私は逆数を計算するためのより賢いアルゴリズムがあることを知っています。それはO(N ^ 2.376)としてスケーリングします。
PPSユーザーモードスケジューリング(WindowsではUMS)ユーザーモードスケジューリング(Windowsでは「UMS」)に慣れていませんが、役に立ちますか?