2016-09-16 130 views
0

我需要一個平行的迭代for循環使用7根芯(或遠離1芯的距離),但另一迭代使用8(全部)內核和下面的代碼試圖:螺紋親和力

Parallel.For(0,2,i=>{ 
    if(i=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(i==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 

這兩次迭代輸出255。因此,parallel.for循環使用單線程,或者一個設置也設置其他迭代親和力。另一個問題是,這是來自延遲敏感的應用程序,所有這些關聯設置都會增加1到15毫秒的延遲時間。

我是否必須明確使用線程,並且應該只將親和性設置一次?

編輯:我試過線程版本,同樣的事情發生。即使有明確的兩個線程,都將255寫入控制檯。現在看來這個命令是針對進程而非線程的。

OpenCL上下文在一次迭代中使用最大內核在cpu上執行內核。其他迭代使用1-2個核心來複制緩衝區並將命令發送到設備。當cpu被opencl使用時,它使用所有內核,並且設備無法獲得足夠的時間來複制緩衝區。設備裂變似乎比解決我狡猾的這個問題更困難。在迭代的Parallel.For

+0

我不知道在這裏有幫助,但是Parallel.For使用線程或任務池?因爲我已經看到它根據任務池的需求創建並破壞了並行度。我很確定線程不這樣做。我的MaxDegree設置爲26,運行了32億比較,活動線程在完成後的六天內會在5和26之間波動。所以雖然我無法幫助,但我對你的問題一定感興趣。 –

+0

我找不到像minParallelismDegree這樣的東西,但我現在嘗試使用匿名函數委託和事件處理程序的純線程。 –

+0

這是您在Parallel.For中設置的選項 - https://msdn.microsoft.com/zh-CN/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspx正如我所說的是無知的,但它可能會幫助你理解這些內在的東西。 –

回答

2

不同的線程親和力

問題是誤導,因爲它是基於假設Parallel API意味着多個線程。 Parallel API確實涉及數據並行處理,但不提供任何保證來調用multiple threads,特別是對於上面提供的代碼,每個線程幾乎沒有任何工作。

對於Parallel API,你可以設置最大並行度,具體如下:

ParallelOptions parallelOption = new ParallelOptions(); 

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount; 

Parallel.For(0, 20, parallelOption, i => 

但是,這永遠無法保證會被調用到並行處理的線程數,因爲線程是從使用ThreadPoolCLR在運行時根據要處理的工作量決定處理是否需要超過one thread

在同一個Parallel循環中,您可以嘗試以下內容,打印Thread.Current.ManageThreadId,這將提供一個清晰的想法,即關於在Parallel循環中調用的線程數。

我是否必須明確使用線程,並且應該只設置一次親和度?

編輯:我試過線程版本,同樣的事情發生。即使有明確的兩個線程,都將255寫入控制檯。現在看來這個命令是針對進程而非線程的。

你可以發佈代碼,對於多線程,你可以嘗試這樣的事情。

Thread[] threadArray = new Thread[2]; 
threadArray[0] = new Thread(<ThreadDelegate>); 
threadArray[1] = new Thread(<ThreadDelegate>); 
threadArray[0]. ProcessorAffinity = <Set Processor Affinity> 
threadArray[1]. ProcessorAffinity = <Set Processor Affinity> 

假設你正確分配的親和力,你可以打印出來,並找到不同的值,請檢查以下ProcessThread.ProcessorAffinity

在上面的鏈接中可以看到的另一個說明中,您可以根據處理器關聯性設置hexadecimal中的值,不確定254, 255表示的值是多少,您是否真的擁有那麼多處理器的服務器。

編輯:

試試下面的編輯你的程序,(基於一個事實,即越來越印了線程ID),現在的時間兩個線程一些圖片,他們都得到相同的值的variable i,他們需要一個local variable,以避免關閉問題

Parallel.For(0,2,i=>{ 
    int local = i; 
    if(local=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(local==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 

編輯2:(大多會無法正常工作,兩個線程可能會增加,實際的邏輯執行前)

int local = -1; 
    Parallel.For(0,2,i=>{ 
    Interlocked.Increment(ref local); 
    if(local=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(local==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 
+0

對於第一部分來說,每次迭代需要20到200毫秒,這是一個負載均衡器,可以平衡所有設備的工作,並使它們的延遲相等。 –

+0

--------------- Thread.Current.ManageThreadId 10 Thread.Current.ManageThreadId 16 ---------------它是這樣但只有第二個變化 –

+0

檢查編輯,如果發生這種情況,主要是這是一個關閉問題,因爲當這兩個線程進入圖片時,'我的價值爲0'爲他們兩個 –