1

使用Parallel Extensions時是否需要關注MemoryBarriers?MemoryBarriers和並行擴展

編輯 - 擬定爲原來的問題是開放式的: (@xanatos的回答是一個我一直在尋找)

舉一個具體的例子:假設我使用Parallel.ForEach和每次迭代設置類中屬性的值(每次迭代設置它自己的特定屬性,沒有兩次迭代設置相同屬性的值)。在調用Parallel.ForEach的同一個線程上,我訪問從Parallel.ForEach設置的屬性。

class Program 
{ 
    static void Main(string[] args) 
    { 
    var t = new Test(); 
    t.InitializePropertiesInParallel(); 
    var a = t.PropA; // Could never be 0? 
    var b = t.PropB; // Could never be 0? 
    } 
} 

public class Test 
{ 
    public int PropA { get; set; } 
    public int PropB { get; set; } 

    public void InitializePropertiesInParallel() 
    { 
    var initializers = new List<Action<int>>() 
    { 
     i => PropA = i, 
     i => PropB = i 
    }; 

    initializers.AsParallel().ForAll(a => a(1)); 
    } 
} 
+0

這取決於你在做什麼並行。 – SLaks 2012-03-13 17:10:08

+0

請詳細說明。在目前的形式下,你的問題有點不確定。 – 2012-03-13 17:10:52

+0

按要求精心佈置。 – dugas 2012-03-14 03:44:47

回答

1

如果每個工人並不需要由其他工作人員準備的數據(所以沒有在那裏,工人1寫入任何情況和工人2讀取A)沒有任何需要MemoryBarrier。當所有任務完成是有Wait充當MemoryBarrier(到底,即使你沒有看到它,冥冥之中有一個同步構造,等待所有的工人來完成)

2

保持一件事記住這裏:cache line invalidation。這是一個複雜的話題,但有a great MSDN article on it here

在這個特定的例子中,它的要點是,因爲你修改了兩個不同線程中的同一個對象實例,即使你沒有碰到內存中完全相同的位置,你將會碰到相同的緩存因此,當處理器1上的第一個線程更改內存時,緩存將在處理器2再次讀取/寫入之前刷新和更新。

這就是說,再次考慮你的具體例子只有兩個道具,這是一個微型優化,絕對不是要擔心的事情。只是要注意,如果你要推斷它。

+1

+1重要的是要注意這是一個性能問題,而不是數據正確性問題。 – xanatos 2012-03-15 10:43:24

+0

非常有趣 - 謝謝。 – dugas 2012-03-15 14:45:09