Parallel.For trva 2x dlhsie ako klasicky for v C#

Programovacie jazyky, rady, poradňa...
yankee
Medium Star
Medium Star
Príspevky: 384
Registrovaný: 06 júl 2006, 1:13

Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa yankee »

vie mi niekto povedat preco v danom prikladde trva paralelny for 2x dlhsie ako klasicky?
ide o C#

Kód: Vybrať všetko

class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            Stopwatch sw2 = new Stopwatch();
            sw.Start();

            for (int i = 0; i < 100; i++ )
                Console.WriteLine(i);
            sw.Stop();

            sw2.Start();
            Parallel.For(0, 100, i =>
            {
                Console.WriteLine(i);
            });
            sw2.Stop();

            Console.WriteLine(sw.Elapsed);
            Console.WriteLine(sw2.Elapsed);
            Console.ReadLine(); 
        }
    }
mam i5-ku 2jadra 4thready.... vdaka
BX
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4572
Registrovaný: 10 jan 2008, 15:30

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa BX »

Odpoveď neviem, ale myslím si, že to bud preto, že tam nemáš vôbec žiadny výpočet iba blbý write, ktorý vypisuje na ten istý stdout.
Takže v prvom for cykle ti prejde 100x write na stdout. V druhom sa ti to rozdelí do pár vlákien a každý píše na stdout = musia na seba čakať + prepínanie kontextu. To čas navýši.
Skús si do oboch hodiť nejaký sleep(akože výpočet) a ten paralelný určite bude oveľa rýchlejší.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8223
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa harrison314 »

BX ma pravdu, ked tam das nejaky vypocet zistis rozdiel, napriklad skus si vypocitat fraktal, alebo poriadne velky faktorial, uvidis rozdiel,
ale paralelizacia nie je taka jednoducha, dost zalezi z akymi datami a ako pracujes

Skus sa pohrat s tymto

Kód: Vybrať všetko

using System;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
class EntryPoint
{
  const int FactorialsToCompute = 100;
  static void Main() {
    var numbers = new ConcurrentDictionary<BigInteger, BigInteger>();

   Func<BigInteger, BigInteger> factorial = null;
     factorial = (n) => ( n == 0 ) ? 1 : n * factorial(n-1);

    var actions = new Action[FactorialsToCompute];
     for( int i = 0; i < FactorialsToCompute; ++i )
     {
       int x = i;
         actions[i] = () => { numbers[x] = factorial(x);};
      }

    Parallel.Invoke( actions );

    for( int i = 0; i < FactorialsToCompute; ++i ) 
       Console.WriteLine( numbers[i] );
   
  }
}
//autoeditácia príspevku (06 Dec 2012, 17:53)
Myslim, ze som o tomto pisal seminarku
yankee
Medium Star
Medium Star
Príspevky: 384
Registrovaný: 06 júl 2006, 1:13

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa yankee »

tak zoberme si napr. tieto dve metody, prva je stale 2x rychlejsia ako druha (ide o vypocet klzavych priemerov) ak bude treba dodam aj konstruktor

Kód: Vybrať všetko

public void calculateSma() {
            Stopwatch sw1 = new Stopwatch();
            double[] sMA = new double[rozsah];

            Console.WriteLine("Zadaj rozsah");
            int interval = int.Parse(Console.ReadLine());
            sw1.Start();
            for (int i = 0; i <= (rozsah - interval); i++) {
                double sum = 0.0;
                int j;
                for (j=i; j < i + interval; j++) {
                    //Console.WriteLine(prices[j]);
                    sum += prices[j];
                }
                sMA[i] = sum / interval;
                //Console.WriteLine();
            }
            sw1.Stop();
            Console.WriteLine("Cas: " + sw1.Elapsed);
            Console.ReadLine();
        }

        public void calculateSmaParallel()
        {
            Stopwatch sw2 = new Stopwatch();
            double[] sMA = new double[rozsah];

            Console.WriteLine("Zadaj rozsah");
            int interval = int.Parse(Console.ReadLine());
            sw2.Start();
            Parallel.For(0, (rozsah - interval + 1), (i) =>
            {
                double sum = 0.0;
                int j;
                for (j = i; j < i + interval; j++)
                {
                    //Console.WriteLine(prices[j]);
                    sum += prices[j];
                }
                sMA[i] = sum / interval;
                //Console.WriteLine();
            });

            sw2.Stop();
            Console.WriteLine("Cas: " + sw2.Elapsed);
            Console.ReadLine();
        }
axxis
Addict
Addict
Používateľov profilový obrázok
Príspevky: 3690
Registrovaný: 29 máj 2007, 21:53
Bydlisko: Spálené mlyny
Kontaktovať používateľa:

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa axxis »

pretoze tam stale pouzivas tu Console, kompilator si na spravi na nu lock a vlaka sa musia cakat (zrejme)
yankee
Medium Star
Medium Star
Príspevky: 384
Registrovaný: 06 júl 2006, 1:13

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa yankee »

Tie Console.WriteLine-y su uz zakomentovane, a sekvencna metoda je stale 2x rychlejsia
BX
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4572
Registrovaný: 10 jan 2008, 15:30

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa BX »

Záleží od vstupných dát. Prejdenie polom je veľmi rýchla operácia. Ak to skúšaš na poli 10 čísel, tak je jasné, že paralelnú verziu znovu zabije réžia. Na poli o veľkost milión už by to mohlo byť vidieť a ak nie, tak tam daj kľudne ešte nejakých 100ms sleep.

Musíš pochopiť, že vlákna sú určené na veľmi zložité - časovo náročné - výpočty. To čo tu s nimi robíš ty sa takýmto výpočtom ani zďaleka nepribližuje.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8223
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Parallel.For trva 2x dlhsie ako klasicky for v C#

Príspevok od používateľa harrison314 »

Aj vela vstupnych dat to moze dost spomalit, pri paralelnom programovani treba mysliet aj na velkost cache pamete procesora,
idalne ked sa ti do nej zmestia vsteky data a robis nad nimi netrivialne vypocty (to ma dalsko od toho co mas).

Na paralelizaciu su velmi vhodne fraktaly (su velmi pekne a daju sa nimi ohurovat baby :D ), evolucne algoritmy, zlozite operacie z maticami, riesenie problemou metodou Monte Carlo, praca z obrazkami a podobne.
Napriklad tu si mozes vyskusat kedy to paralelizacia zrychluje a kedy zas spomaluje http://blogs.msdn.com/b/lukeh/archive/2 ... racer.aspx
PS: uznavam je to extremny priklad.
Napísať odpoveď