0. なぜこんなことを書くのか
並列処理とは何なのか、調べたのでアウトプットとしてここに残します。
ドキュメントを読む練習も兼ねているので、参考資料は主にMicrosoftのドキュメントになります
1. 並列処理とは
複数のタスクが異なるCPUコアで同時に実行されること。
計算処理系などの比較的小さくて独立した処理を別々のコアで実行することで、複数コアを持つハードウェアのパフォーマンスを引き出すための手法。
1-1. 間違えやすい単語
- 並行処理
並行処理とは、複数のプロセスが実行可能状態であること。
実際には同時にプロセスが動いていなくても、人間の目には同時に処理が行われているように見えている。マルチタスクOSではシングルコアで各プロセスをナノ秒ごとのタイムスライスで区切って高速に切り替えながら1処理ずつ行っている。
- 非同期処理
根幹として、非同期処理というものがベースにあり、その用途やシナリオによってバックグラウンド処理、並列処理と分かれるイメージ。
2. .NET Frameworksでの並列処理
2-1. Parallel.For
Parallel.For(Int32, Int32, ParallelOptions, Action)
第1引数
Int32
開始インデックス
第2引数
Int32
終了インデックス
第3引数
ParallelOptions
この操作の動作を構成するオブジェクト
第4引数
Action
1回のイテレーションにつき1回呼び出されるデリゲート
戻り値
完了したループの部分に関する情報を格納している構造
- 具体例
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Parallel.For(0, 10, i =>
{
Process(i);
});
}
static void Process(int i)
{
Console.WriteLine($"Processing number: {i}");
// シミュレーション用の待機
System.Threading.Thread.Sleep(1000);
}
}
2-2. Parallel.ForEach
Parallel.ForEach(IEnumerable, ParallelOptions, Action)
第1引数
IEnumerable
ソース内のデータ型
第2引数
ParallelOptions
この操作の動作を構成するオブジェクト
第3引数
Action
1回のイテレーションにつき1回呼び出されるデリゲート
戻り値
完了したループの部分に関する情報を格納している構造
- 具体例
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Parallel.ForEach(numbers, number => { Process(number); });
}
static void Process(int number)
{
Console.WriteLine($"Processing number: {number}"); // シミュレーション用の待機
System.Threading.Thread.Sleep(1000);
}
}
2-3. Parallel.Invoke
Parallel.Invoke(ParallelOptions, Action[])
第1引数
ParallelOptions
この操作の動作を構成するオブジェクト
第2引数
Action[]
実行対象のアクションの配列
- 具体例
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Parallel.Invoke(
() => Process("Task 1"),
() => Process("Task 2"),
() => Process("Task 3")
);
}
static void Process(string taskName)
{
Console.WriteLine($"{taskName} is running");
// シミュレーション用の待機
System.Threading.Thread.Sleep(1000);
}
}
2-4. ParallelOptions
-
CancellationToken
並列処理を途中でキャンセルするための仕組み
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var cts = new CancellationTokenSource();
var options = new ParallelOptions { CancellationToken = cts.Token };
// 別のスレッドで一定時間後にキャンセルを実行
Task.Run(() =>
{
Thread.Sleep(2000); // 2秒待機
cts.Cancel();
});
try
{
Parallel.For(0, 10, options, i =>
{
Console.WriteLine($"Processing number: {i}");
Thread.Sleep(1000);
options.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was canceled.");
}
}
}
-
MaxDegreeOfParallelism
並列処理の最大スレッド数を指定するためのもの
ParallelOptions option = new ParallelOption();
option.MaxDegereeOfParallelism = 2;
Parallel.For(0, 100, option, i =>
{
Console.Write(i + ",");
});
-
TaskScheduler
このParallelOptionsインスタンスに関連付けられているTaskSchedulerを取得または設定する。このプロパティをnullに設定すると、現在のスケジューラーが使用される。
あとがき
調べた感想としては、「ほえぇ、そんなのがあるんだ」って感じです。
次は実際にコードを組み、その恩恵を感じたいと思います。
参考文献