> [...]
> > Aby sporzystac z tej gigantycznej mocy obliczeniowej trzeba jednak pokonac dwa problemy
> > Pierwszym jest odnalezienie lub stworzenie wektorowego algorytmu
> > rozwiazujacego twój problem matematyczny.
> > Drugim jest odpowiednie zaprogramowanie jednostki vertexów znajdujacej sie w GPU
> > tak aby wykonal dla ciebie sposowne obliczenia.
> > Pierwszy problem musisz rozwiazac zamodzielnie
> > gdyz tylko ty znasz tematyke obliczen którymi bedziesz sie zajmowac.
> > Jesli chodzi o drugi, to muszisz odnalezc biblioteke
> > która pozwoli ci wydobyc moc kryjaca sie w GPU.
> [...]
>
> Koncepcja ciekawa, ale w praktyce nierealna. Czesc kodu, ktora ja
> zamierzam napisac jest duza objetosciowo, ale zajmuje malo czasu
> procesora. Czescia ktora bedzie najbardziej wymagajaca obliczeniowo
> jest procedurka diagonalizujaca duza ilosc sredniej wielkosci dosc
> wrednych zespolonych macierzy. A zeby taka PRZYZWOITA procedurke
> napisac samemu, to trzeba sie na tym znac, bo z tego co slyszalem, to
> zadanie nie jest calkiem trywialne. Mysle wiec, ze zebym ja prosty
> fizyko-chemik zaprogramowal efektywnie taka procedurke na GPU, to
> musialoby w Wisle tak duzo wody uplynac, ze sprawa jest po prostu
> nieoplacalna ;-)
Cały trik z biblioteka Accelerator polega własnie na tym
że prawie całkowicie odcina cię od wiedzy o sprzęcie
wykorzystywanym w czasie obliczeń.
Jedyna informacja jaką potrzebujesz to wiedza
o maksymalnym rozmiarze tekstur
które mogą być stosowane w twojej karcie graficznej.
Przykładowo moja karta graficzna obecnie to RADEON 9600
i dla niej maksymalna tekstura to 2048x2048
tak więc maksymalny rozmiar macierzy na
których moge wykonywać obliczenia
to własnie 2048 na 2048 licz zmiennoprzecinkowych
całkowitych, lub wartości boolean.
W aplikacji jedynym jawnym odwołaniej do grafiki jest wywołanie metody
ParallelArrays.InitGPU();
Znasz zapewne metode Monte Carlo
wyznaczania pzrybliżonej wartości liczby PI
(http://math.fullerton.edu/mathews/n2003/MonteCarloPiMod.html)
Oto jej implementacja wykorzystujaca biblioteke Accellerator:
<code lang="c#">
//(c) Microsoft Corporation. All rights reserved.
//
// Monnte Carlo pi aproximation
using System;
using Microsoft.Research.DataParallelArrays;
using PA = Microsoft.Research.DataParallelArrays.ParallelArrays;
public class MonteCarlo
{
public static void Main()
{
// create randomly generated samples in the unit square centered on (0,0)
int iSize = 1500;
float[,] x = new float[iSize, iSize]; // x coordinate
float[,] y = new float[iSize, iSize]; // y coordinate
int i, j;
// create an x and y arrays of random numbers between 0 and 1
Random rnd = new Random();
for (i = 0; i < iSize - 1; i++)
for (j = 0; j < iSize - 1; j++)
{
x[i, j] = (float)rnd.NextDouble();
y[i, j] = (float)rnd.NextDouble();
}
PA.InitGPU();
// make x and y data parallel arrays
DisposableFloatParallelArray parallelX = new DisposableFloatParallelArray(x);
DisposableFloatParallelArray parallelY = new DisposableFloatParallelArray(y);
// center them about (0, 0) with range (-1, 1)
FloatParallelArray parallelXCentered;
FloatParallelArray parallelYCentered;
parallelXCentered = PA.Multiply(ParallelArrays.Subtract(parallelX, 0.5F), 2.0F);
parallelYCentered = PA.Multiply(ParallelArrays.Subtract(parallelY, 0.5F), 2.0F);
// calculate distance of (x,y) from 0, ie. Sqrt(x^2 + y^2)
FloatParallelArray parallelXSquare;
FloatParallelArray parallelYSquare;
FloatParallelArray parallelDistance;
parallelXSquare = PA.Multiply(parallelXCentered, parallelXCentered);
parallelYSquare = PA.Multiply(parallelYCentered, parallelYCentered);
parallelDistance = PA.Sqrt(PA.Add(parallelXSquare, parallelYSquare));
float[,] test = new float[iSize, iSize];
ParallelArrays.ToArray(parallelDistance, out test);
// create an array of 1's if distance < 1, 0 if distance > 1
FloatParallelArray parallelOne = new FloatParallelArray(1.0F, parallelX.Shape);
FloatParallelArray parallelZero = new FloatParallelArray(0.0F, parallelX.Shape);
FloatParallelArray parallelInCircle;
parallelInCircle =
PA.Select(PA.Subtract(parallelOne, parallelDistance), parallelOne, parallelZero);
// the number inside the circle is the sum of the entire InCircle array
FloatParallelArray parallelCountInCircle;
parallelCountInCircle = PA.Sum(parallelInCircle);
float[] inCircle = new float[1];
PA.ToArray(parallelCountInCircle, out inCircle);
parallelX.Dispose();
parallelY.Dispose();
// approximate pi--area of unit circle is pi
// area of square from -1,1 is 4
// inCircle/(total number of points) == pi/4
float pi;
pi = 4 * inCircle[0] / (iSize * iSize);
System.Console.WriteLine("Pi is approximately " + pi.ToString());
PA.UnInit();
// Prompt user for exit
Console.WriteLine("Press Enter to Exit");
Console.ReadLine();
}
}
</code>
Jak widzisz cały algorytm został sprowadzony
do kilku prostych operacji na macierzech.
Cały ciężar odpowiedniego przetłumaczenia tego na instrukcje GPU
został przerzucony na biblioteke uruchomieniową.
Tak wiec programist/fizyk/chemik wcale nie musi wiedzieć
że wszystkie jego obliczenia wykonuje jakiś procesor wektorowy
zaszyty w karcie graficznej.
-- ____________ Robert WinklerReceived on Thu Oct 26 18:30:06 2006
To archiwum zostało wygenerowane przez hypermail 2.1.8 : Thu 26 Oct 2006 - 18:51:25 MET DST