2010-09-15 27 views
7

Kısa bir süre önce C# .net'e taşındım.Parallel.For ne zaman kullanılır?

Parallel'ı seviyorum. Ne zaman kullanacağınızı ve ne zaman kullanacağınızdan emin değilim. Siparişin benim için önemli olmadığını biliyorum - kullanacağım.

Ancak Parallels ile çalışma yükü ile ilgili herhangi bir test var mı? Anlamım, eğer döngüğüm sadece 10 kez çalışırsa (ve çok az mantık yürütürse) - Parallels'ten kaçınmalı mıyım? Herhangi bir başparmak kuralları var mı?

+0

Bu konuyu "kapsayan Microsoft'tan gerçekten iyi ücretsiz e-kitap [Paralel Programlama Desteği: .NET Framework 4 ile Paralel Kalıpları Anlama ve Uygulama] (https://www.microsoft.com/en-us/download/details.aspx?id=19222) " –

cevap

4

Performans sorunu yoksa, Parallel.For kullanmaktan kaçınırım.

Eşzamanlı çalışan kodların yazılması, genellikle tek iş parçacıklı kod yazılmasından daha zordur. Ayrıca bir eşzamanlılık sorunu nedeniyle bir hata yaparsanız, hata ayıklamak zor olabilir. Örneğin, hata sadece bazen meydana gelebilir ve kolayca tekrarlanamaz. Artırılmış performansa özel bir gereksiniminiz olmadıkça, bunu basit tutmanızı ve sıradan bir döngüyü tek bir iş parçacığı üzerinde kullanmanızı öneririm.

+0

Katılıyorum - don ' Sadece kullan çünkü orası var. ile gerçek bir sorunu çözmeye çalışın. Ayrıca, profilleme arkadaşın;) –

+0

Burada "performansın bir sorun" olduğunu düşünüyorum. –

+0

Mark'a katılıyorum. Bir iş için mümkün olan en az kaynakları kullanın. – Josh

0

SQLite Hakkında SSS: 'Threads are evil. Onlardan kaçınmak '

Paralelizasyon performans için kullanışlıdır. Uygulama performans optimizasyonu, yazılım tasarımında en çok sezgisel olan şeylerden biridir ve doğru ölçüm araçlarını kullanarak aşırı dikkatle yapılmalıdır, yoksa sadece komik görünecektir. Bazıları, açıkça hiçbir değeri olmayan ve çok fazla hasara neden olan milisaniye yerine mikro saniyede yanıt vermek için UI kodunu en iyi duruma getirecektir.

+0

Bunun içinde bazı gerçek, ama tamamen çok basit. Bakınız örneğin http: // stackoverflow.com/sorular/3415519/is-orada-bir-noktadan-çoklu kullanım/3415563 # 3415563 –

1

Parallel.For döngüsü, bir döngüde her yineleme başına bir temsilci çağırmak suretiyle bir döngüde işi yürütmek için ThreadPool'u kullanır.

aşağıdaki gibi sunulabilir nasıl Parallel.For eserler genel fikir:

public static void MyParallelFor(int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body) 
{ 
    // Get the number of processors, initialize the number of remaining 
    // threads, and set the starting point for the iteration. 
    int numProcs = Environment.ProcessorCount; 
    int remainingWorkItems = numProcs; 
    int nextIteration = inclusiveLowerBound; 
    using (ManualResetEvent mre = new ManualResetEvent(false)) 
    { 
     // Create each of the work items. 
     for (int p = 0; p < numProcs; p++) 
     { 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       int index; 
       while ((index = Interlocked.Increment(ref nextIteration) - 1) < exclusiveUpperBound) 
        body(index); 

       if (Interlocked.Decrement(ref remainingWorkItems) == 0) 
        mre.Set(); 
      }); 
     } 
     // Wait for all threads to complete. 
     mre.WaitOne(); 
    } 
} 

Parallel.For tamamlanan döngü ayrıntıları içerir ParallelLoopResult değer türünü döndürür. aşağıdaki gibi onun aşırı biri:

public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body); 

paralel yürütme her zaman seri yürütme daha hızlı olmadığını fark etmek önemlidir. Paralel kullanılıp kullanılmayacağına karar vermek için, bir döngünün yinelemesi başına yapacağı iş yükünü tahmin etmelisiniz. Döngü tarafından gerçekte gerçekleştirilen iş, iplik senkronizasyon maliyetine nispeten küçükse, sıradan döngü kullanmak daha iyidir. döngü performansı için seri daha hızlı olduğu paralel olduğunda

Bu örnek birisidir:

static void Main(string[] args) 
{ 
    Action<int> action = new Action<int>(SimpleMethod); 

    // ordinary For loop performance estimation 
    var sw = Stopwatch.StartNew(); 

    for(int i = 0; i < 1000; i++) 
     action(i); 

    Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds); 

    // parallel For loop performance estimation 
    sw = Stopwatch.StartNew(); 

    Parallel.For(0, 1000, action); 

    Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds); 
} 

static void SimpleMethod(int index) 
{ 
    int d = 1; 
    int result = index/d; 
} 

Çıktı: İşte

0.0001963 sec. 
0.0346729 sec. 
İlgili konular