我試圖加快我用C#編寫的算法。我想到的第一件事是讓它平行。該算法必須運行大量(〜數百萬)的2D片段,每個片段獨立於其他片段。C#多線程沒有使用足夠的CPU
下面是代碼:`
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一個查詢到空間的數據結構(配額樹)被執行,則發生一些計算。
無鎖在整個過程中進行。 使用No Disk。
你有什麼建議可能導致CPU只能達到40-60的使用?
我也嘗試將num任務更改爲4,6和8。沒有重大變化。
我正在考慮GC,但沒有太多的工作可以阻止它運行。
編輯: 通過減少一些類的內存使用情況,我設法改善了一點點的CPU使用率,現在它運行在70%左右。
另一方面,通過提高QuadTree的水平閾值,我獲得了顯着的性能提升。
每個單線程只能關閉一個物理內核。也許這就是你所面對的。另外'Task.WaitAll(tasks);'只會在所有任務完成時繼續執行,因此其中一些可能在所有任務完成之前就已經完成。 – Karolis
您需要提供[mcve]。我們確實應該有能夠複製粘貼並運行以查看問題的代碼。理想情況下,我們也應該有一個非平行版本的代碼,以便我們可以看到基本計算是什麼。 – Enigmativity
不知道你的意圖是什麼,但你可以並行和檢查。簡單的做法是使用Parallel for循環。您還可以設置再次取決於處理器內核的處理器親和性。 –