私はC#で書いたアルゴリズムを高速化しようとしています。私が最初に考えたのは、それを平行にすることです。C#マルチスレッドで十分なCPUが使用されない
アルゴリズムは、多くの(〜数百万)の2Dセグメントで実行する必要があり、各セグメントは他のセグメントとは独立しています。ここ
コードである: `空間データ構造に
private void DoMapping(Segment[] image, CancellationToken ct, int numTasks = 3)
{
long time = Environment.TickCount;
LaserOutput = new List<Vector3[]>();
NormalsOutput = new List<Vector3>();
Task< Tuple < List<Vector3[]>, List <Vector3>>>[] tasks = new Task<Tuple<List<Vector3[]>, List<Vector3>>>[numTasks];
int perTaskSegments = image.Length/numTasks;
for (int taskIndex = 0; taskIndex < tasks.Length; taskIndex++)
{
int nseg = perTaskSegments * (taskIndex + 1) + (taskIndex == tasks.Length - 1 ? image.Length % tasks.Length : 0);
int from = perTaskSegments * taskIndex;
Tuple<int, int, Segment[], CancellationToken> obj = new Tuple<int, int, Segment[], CancellationToken>(from, nseg, image, ct);
tasks[taskIndex] = Task.Factory.StartNew(DoComputationsAction, obj, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
Task.WaitAll(tasks);
for (int taskIndex = 0; taskIndex < tasks.Length; taskIndex++)
{
LaserOutput.AddRange(tasks[taskIndex].Result.Item1);
NormalsOutput.AddRange(tasks[taskIndex].Result.Item2);
}
}
private Tuple<List<Vector3[]>, List<Vector3>> DoComputationsAction(object obj)
{
Tuple<int, int, Segment[], CancellationToken> parm = obj as Tuple<int, int, Segment[], CancellationToken>;
List<Vector3[]> tmpLaser = new List<Vector3[]>();
List<Vector3> tmpNormals = new List<Vector3>();
bool errorOccured = false;
for (int segCounter = parm.Item1; segCounter < parm.Item2 && !errorOccured; segCounter++)
{
if (parm.Item4.IsCancellationRequested)
break;
try
{
var res = SplitOverMap(parm.Item3[segCounter], (string error) => {
errorOccured = true;
MessageBox.Show(error, "An error occured", MessageBoxButtons.OK, MessageBoxIcon.Error);
Logger.Log("An error occured while mapping data to 3d.");
});
if (res != null)
{
tmpLaser.AddRange(res.Item1);
tmpNormals.AddRange(res.Item2);
}
}
catch (Exception e)
{
Logger.Log("An error occured while calculating 3d map. Skipping polyline." + e.Message);
}
}
return new Tuple<List<Vector3[]>, List<Vector3>>(tmpLaser, tmpNormals);
}`
内部SplitOverMap クエリ(のqtree)を行い、その後、いくつかの計算が発生します。
ロックなしは、プロセス全体で実行されます。 No Diskが使用されています。
CPUが40-60回しか使用できない原因について何か提案がありますか?
numタスクを4,6,8に変更しようとしました。大きな変更はありません。
私はGCについて考えていますが、実行するのを防ぐためにできることはたくさんありません。
EDIT: 私は少しにCPU使用率を向上させるために管理しているクラスのいくつかのメモリ使用量を減らすことにより、今では70%前後を実行します。
一方、QuadTreeのレベルスレッショルドを上げることによって、私は大幅なパフォーマンスの向上が得られました。
各シングルスレッドは、単一の物理コアのみを使用できます。多分それはあなたが直面しているものです。また、 'Task.WaitAll(tasks);'はすべてのタスクが完了したときにのみ動くので、それらのいくつかはすべて完了する前に既に完了しているかもしれません。 – Karolis
あなたは[mcve]を提供する必要があります。ペーストをコピーして問題を見るために実行できるコードが本当に必要です。理想的には、このコードの非並行バージョンを用意して、基本的な計算がわかるようにする必要があります。 – Enigmativity
あなたの意図はわかりませんが、パラレルにして確認できます。それを行う簡単な方法は、Parallel forループを使用することです。やはりプロセッサのコアに依存するプロセッサアフィニティを設定することができます。 –