2013-12-18 6 views
5

मैं किसी और के .NET 4 खुला स्रोत समतल कण-गत्यात्मकता कोड का उपयोग कर रहा नेट के लिए और मैं एक एकता परियोजना है जो आप केवल पर भरोसा कर सकते नेट पर निर्भर होने के लिए यह कन्वर्ट करने के लिए कोशिश कर रहा हूँ 2 मानकों। दुर्भाग्य से कोड समांतर वर्ग का उपयोग करता है (जो कमाल है!) लेकिन वह अधिक अस्पष्ट ओवरलोड का उपयोग करता था। क्या कोई भी एक बड़ी चीज के बिना .NET 2 में एक ही चीज़ को हासिल करने का एक अच्छा तरीका देख सकता है?परिवर्तित .NET 4 थ्रेडिंग 2

Parallel.For(
     0, 
     _numActiveParticles, 
     () => new Vector2[MAX_PARTICLES], 
     (i, state, accumulatedDelta) => calculateForce(_activeParticles[i], accumulatedDelta), 
     (accumulatedDelta) => 
     { 
      lock (_calculateForcesLock) 
      { 
       for (int i = _numActiveParticles - 1; i >= 0; i--) 
       { 
        int index = _activeParticles[i]; 
        _delta[index] += accumulatedDelta[index]/MULTIPLIER; 
       } 
      } 
     } 
    ); 

मुझे लगता है कि यह है कि क्या कोड करता है (गैर थ्रेडेड) है:

for (int i = 0; i < _numActiveParticles; i++) 
    { 
     Vector2[] temp = new Vector2[MAX_PARTICLES]; 
     temp = calculateForce(_activeParticles[i], temp); 


     for (int k = _numActiveParticles - 1; k >= 0; k--) 
     { 
      int index = _activeParticles[k]; 
      _delta[index] += temp[index]/MULTIPLIER; 
     } 
    } 
+2

आप मिल सकती है यह सहायक http://stackoverflow.com/q/12386686/809009 –

+0

@OndrejJanacek धन्यवाद कि सहायक लेकिन मैं 100% निश्चित नहीं हूं कि समांतर संस्करण क्या कर रहा है, इसलिए मैं यह सुनिश्चित करना चाहता हूं कि मैं इसे सही तरीके से अनुवाद करूं। – PorcupineRending

+0

मुझे नहीं लगता कि आपकी समझ सही है। आप कहीं भी 'temp' चर का उपयोग नहीं कर रहे हैं। इसे पढ़ें: http://msdn.microsoft.com/en-us/library/ff963547.aspx –

उत्तर

1

आपकी दूसरी कोड सही नहीं है। मुझे लगता है कि सही कोड इस तरह है:

var accumulatedDelta= new Vector2[MAX_PARTICLES]; 

for(int i = 0; i < _numActiveParticles; ++i) 
{ 
    accumulatedDelta = calculateForce(_activeParticles[i], accumulatedDelta); 
} 

for (int i = _numActiveParticles - 1; i >= 0; i--) 
{ 
    int index = _activeParticles[i]; 
    _delta[index] += accumulatedDelta[index]/MULTIPLIER; 
} 

मैं नहीं जानता कि क्या .net2 है और क्या नहीं करता है। लेकिन आप Parallel.For स्वयं को अनुकरण कर सकते हैं। Parallel.For के इस अधिभार की

स्पष्टीकरण यह है:

पहले पैरामीटर: पाश के सूचकांक शुरू

दूसरा पैरामीटर: पाश के अंत सूचकांक

तीसरा पैरामीटर: एक प्रतिनिधि उस कार्य को स्थानीय डेटा पैदा करेगा । प्रत्येक हर धागे के लिए Parallel.For उपयोग (एक कार्य) इस प्रतिनिधि को बुलाया जाएगा और localInit डेटा वापस कर दिया जाएगा।

चौथा पैरामीटर: एक प्रतिनिधि है कि for के शरीर के रूप में कार्य। बॉडी प्रतिनिधि के पहले निष्पादन में, यह प्रतिनिधि प्रीवीज प्रतिनिधि (localInit) द्वारा बनाए गए डेटा को पुनर्प्राप्त करेगा। प्रत्येक बाद के लूप में, बॉडी प्रतिनिधि localInit बदल सकता है और फिर उसे अगले शरीर निष्पादन में वापस कर सकता है। बॉडी प्रतिनिधि के अंतिम निष्पादन में, localInit डेटा अंतिम प्रतिनिधि को पास किया जाएगा।

अंतिम पैरामीटर: एक और प्रतिनिधि है कि प्रत्येक कार्य प्रति बुलाया जाएगा, जब कार्य यह समाप्त हो गया है काम है। localInit इस प्रतिनिधि को पास कर दिया जाएगा। चूंकि इस प्रतिनिधि को कई कार्यों द्वारा समवर्ती कहा जा सकता है, इसलिए आपको अपने साझा डेटा की रक्षा करनी होगी।

संपादित करें:

ParallelFor का एक संस्करण इस तरह हो सकता है:

public static void ParallerFor<TLocal>(int startIndex, int endIndex, Func<TLocal> initData, Func<int, TLocal, TLocal> body, Action<TLocal> finalizer) 
    { 
     int numThreads = Environment.ProcessorCount; 
     int chunkOffset = ((endIndex - startIndex)/numThreads) + 1; 

     Task[] tasks = new Task[numThreads]; 

     Enumerable.Range(0, numThreads).ToList().ForEach(x => 
      { 
       int start = x * chunkOffset; 
       int end = ((x + 1) * chunkOffset); 
       end = end > endIndex ? endIndex : end; 

       tasks[x] = Task.Factory.StartNew(() => 
       { 
        TLocal init = initData(); 

        for(int i = start; i < end; ++i) 
        { 
         init = body(i, init); 
        } 

        finalizer(init); 
       }); 
      }); 

     Task.WhenAll(tasks).Wait(); 
    } 
+0

समानांतर को पुन: कार्यान्वित करने के लिए कार्य वर्ग का उपयोग करना। मूड की तरह है। यदि आपके पास एक है, तो आपके पास दूसरा भी है (दोनों .net 4 और ऊपर हैं)। –

+0

@ ईसाई.के आपके उल्लेख के लिए धन्यवाद। मुझे नहीं पता कि समानांतर सहायक ''net 2' किस प्रकार है, लेकिन' टास्क' को मैन्युअल 'थ्रेड' के साथ बदलना एक सीधा काम है। – MRB

+0

आप एमएसडीएन देख सकते हैं। यह आपको बताएगा। ध्यान दें कि एक कार्य धागे के समान नहीं है (कम से कम थ्रेड पूल का उपयोग करें और सादा धागा नहीं)। आम तौर पर, टीपीएल कार्यक्षमता को पुन: कार्यान्वित करना सही और कुशल पाने के लिए गैर तुच्छ है। इंटरनेट पर इसके बारे में बहुत सारी सामग्री। –