
Ta papuga była kiedyś czerwona
Wiele osób narzeka na platformy z maszyną wirtualną (.net, Java), twierdząc, że programy działające na nich mają gorszą wydajność niż te uruchomione w swoim natywnym środowisku. Nie mam zamiaru zaczynać kolejnej świętej wojny, chciałbym jednak przeciwnikom pokazać, że program .net-owy może być bardzo szybki.
Można bowiem w ogóle nie przejmować się wydajnością maszyny wirtualnej i cały ciężar obliczeniowy zrzucić na sprzęt bardziej odpowiedni do tego typu zadań. Co powiecie na kartę graficzną? OK, normalnie można by zastosować CUDA, ale jak z owych cudów skorzystać w platformie zarządzanej? Odpowiedź może być prosta: użyć mechanizmów współpracy kodu zarządzanego i natywnego, albo jeszcze prostsza: skorzystać z gotowego kodu, który wykona za nas brudną robotę.
Biblioteka nazywa się CUDA.net (jakżeby inaczej). Co ważne, jest cały czas rozwijana. Jak można dzięki niej skorzystać z dobrodziejstw CUDA w programie .net-owym? Prosto:
- piszemy zwykłą aplikację
- piszemy funkcje wykonywane na urządzeniu obliczeniowym (pliki .cu)
- dodajemy build rule nvcc *.cu --cubin
- dodajemy referencję do CUDA.net i dopisujemy kod pośredniczący, który wygląda mniej więcej tak:
int BLOCK_SIZE = 256;
CUDA cuda = new CUDA(0, true);
cuda.LoadModule(Path.Combine(Environment.CurrentDirectory,
"kernel.cubin"));
CUfunction func = cuda.GetModuleFunction("hslfilter");
cuda.SetParameter(func, 0, (uint)dev_values.Pointer);
cuda.SetParameter(func, (int)IntPtr.Size, ratio);
cuda.SetParameterSize(func, (uint)IntPtr.Size+4);
cuda.SetFunctionBlockShape(func, BLOCK_SIZE, 1, 1);
cuda.Launch(func, (input.Length / 3) / BLOCK_SIZE, 1);
output = new byte[input.Length];
cuda.CopyDeviceToHost(dev_values, output);
cuda.Free(dev_values);
Jak widać, nie jest to dużo bardziej skomplikowane niż użycie CUDA z poziomu C(++), a efekt przyrostu wydajności jest dokładnie ten sam. Pliki .cu są kompilowane do plików .cubin, z których możemy już swobodnie korzystać w dowolnej aplikacji.
A tu linki do całego programu, który wykonuje prostą operację na obrazku (obraca kolory o 36 stopni):
- Binarka (wymaga karty wspierającej CUDA)
- Źródła (VS 2008)

