Sunteți pe pagina 1din 4

Parallel Loops (.

NET)
Șablonul Parallel Loop se folosește atunci când este nevoie de realizarea unor
operații independente pentru fiecare element al unei colecții sau pentru un
număr fix de iterații. Pașii unei bucle sunt independenți dacă aceștia nu scriu în
locații de memorie sau fișiere citite de alți pași.

Sintaxa unei bucle în paralel este similară cu cea a unui for sau foreach, dar
bucla în paralel rulează mai repede pe un calculator ce conține nuclee
disponibile. Altă diferență este reprezentată de faptul că, spre deosebire de o
buclă secvențială, ordinea execuției nu este definită într-o buclă paralelă. Pașii,
de obicei, au loc, în paralel, în același timp. Uneori, doi pași au loc în ordinea
opusă celei care ar exista într-o buclă secvențială. Singura garanție este aceea
că, toate iterațiile buclei vor fi rulat pana la finalizarea buclei.

Modificarea unei bucle secvențiale într-una paralelă, se realizează foarte ușor.


De asemenea, este ușor de utilizat o buclă paralelă, chiar și atunci când nu este
necesară. Acest lucru, are ca explicație faptul că, poate fi dificilă recunoașterea
pașilor ca fiind independenți unii de ceilalți. Este necesar mult exercițiu pentru
a recunoaște un pas independent de altul. Uneori, folosind acest șablon, într-o
buclă ce conține pași dependenți, cauzează un cu totul alt rezultat față de cel
așteptat, poate chiar și blocarea acestuia. Alteori, apare un bug o dată la un
milion de execuții. Cu alte cuvinte, cuvântul ”independent” este partea cheie a
definiției acestui șablon.

Pentru buclele în paralel, nu este necesară specificarea gradului de paralelism.


Buclele funcționează corect, indiferent de nucleele disponibile. Dacă există un
singur nucleu, performanța se apropie de cea a echivalentului secvențial. Dacă
există nuclee multiple, performanța este îmbunătățită; în majoritatea cazurilor,
performanța crește proporțional cu numărul de nuclee.

Platforma .NET include ambele bucle paralele pentru for și foreach.


Exemplu de calcul în paralel: înmulțirea a 2 matrice

using System;
using System.Diagnostics;
using System.Threading.Tasks;

class MultiplyMatrices
{
// Sequential
static void MultiplyMatricesS(double[,] matA, double[,] matB,
double[,] result)
{
int matACols = matA.GetLength(1);
int matBCols = matB.GetLength(1);
int matARows = matA.GetLength(0);

for (int i = 0; i < matARows; i++)


{
for (int j = 0; j < matBCols; j++)
{
double multiply = 0;
for (int k = 0; k < matACols; k++)
{
multiply += matA[i, k] * matB[k, j];
}
result[i, j] += multiply;
}
}
}
// End Sequential

//Parallel
static void MultiplyMatricesP(double[,] matA, double[,] matB, double[,] result)
{
int matACols = matA.GetLength(1);
int matBCols = matB.GetLength(1);
int matARows = matA.GetLength(0);

Parallel.For(0, matARows, i =>


{
for (int j = 0; j < matBCols; j++)
{
double multiply = 0;
for (int k = 0; k < matACols; k++)
{
multiply += matA[i, k] * matB[k, j];
}
result[i, j] = multiply;
}
}); // Parallel For
}
// End Parallel

// Main
static void Main(string[] args)
{
// Set up matrices.
int colNr = 180;
int rowNr = 2000;
int colNr2 = 270;
double[,] m1 = InitializeMatrix(rowNr, colNr);
double[,] m2 = InitializeMatrix(colNr, colNr2);
double[,] result = new double[rowNr, colNr2];

// Sequential version
Console.Error.WriteLine("Executing sequential version...");
Stopwatch watch = new Stopwatch();
watch.Start();

MultiplyMatricesS(m1, m2, result);


watch.Stop();
Console.Error.WriteLine("Sequential version time (ms): {0}",
watch.ElapsedMilliseconds);

// Print result

// Print(rowNr, colNr2, result);

// Reset timer and results matrix


watch.Reset();
result = new double[rowNr, colNr2];

// Parallel version
Console.Error.WriteLine("Executing parallel version...");
watch.Start();
MultiplyMatricesP(m1, m2, result);
watch.Stop();
Console.Error.WriteLine("Parallel version time (ms): {0}",
watch.ElapsedMilliseconds);

Print(rowNr, colNr2, result);

//Keep console window opened


Console.Error.WriteLine("Press any key to exit.");
Console.ReadKey();
}
//End Main

//Other Methods
static double[,] InitializeMatrix(int rows, int cols)
{
double[,] matrix = new double[rows, cols];

Random r = new Random();


for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
matrix[i, j] = r.Next(100);
}
}
return matrix;
}

private static void Print(int rowCount, int colCount, double[,] matrix)


{

Console.WindowWidth = 160;
Console.WriteLine();
for (int x = 0; x < rowCount; x++)
{
Console.WriteLine("ROW {0}: ", x);
for (int y = 0; y < colCount; y++)
{
Console.Write("{0} ", matrix[x, y]);
}
Console.WriteLine();
}

Console.WriteLine();

}
// End Other Methods
}

S-ar putea să vă placă și