Ai giorni d'oggi per effettuare il calcolo parallelo, invece di usare un cluster di computer, si possono usare i diversi core del processore oppure usare la scheda grafica con la sua GPU (mediante le librerie CUDA di NVidia o le piu' generiche OpenCL che possono girare su AMD, NVidia e Intel)
La strategia utilizzata in CUDA e OpenCL e' piu' o meno la stessa ovvero si scrive il codice di un kernel, ovvero della elaborazione che verra' eseguita su ogni unita' di elaborazione, e poi il codice che gestisce la coda dei processi e la distribuzione alle varie unita' di elaborazione
Un esempio di kernel per Mandelbrot e' il seguente
-------------------------------------------------------------------
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
double trans_x(int x, int N)
{
return 3.0 * ((double)x / N) - 2.0;
}
double trans_y(int y, int N)
{
return 3.0 * ((double)y / N) - 1.5;
}
double mag2(double r, double i)
{
return r * r + i * i;
}
__kernel void mandel(__global double* out, int N, int depth, double escape2)
{
size_t idx = get_global_id(0);
double z0_r = trans_x(idx % N, N);
double z0_i = trans_y(idx / N, N);
double z_r = 0;
double z_i = 0;
int k = 0;
for(; k <= depth && mag2(z_r, z_i) < escape2 ; ++k)
{
double t_r = z_r; double t_i = z_i;
z_r = t_r * t_r - t_i * t_i + z0_r;
z_i = 2 * t_r * t_i + z0_i;
}
out[idx] = log(k + 1.0 - log(log(max(mag2(z_r, z_i), escape2)) / 2.0) / log(2.0));
}
Per mettere alla prova quanto vantaggio c'e' nell'usare OpenCL per il calcolo di Mandelbrot ho usato un portatile Surface Pro 2 con scheda video Intel HD 4400 ed il programma reperibile a questo link.
Come test ho provato il Miniset level 2 (1000 iterazioni per punto) con i seguenti risultati
- C float, single thread :1.71 s
- C float, 4 thread : 0.61 s
- C float, 8 thread : 0.59 s
- C fixed-point 128 bit 2 thread : 22.5 s
- OpenCl CPU float : 0.36 s
- OpenCL CPU double : 0.4 s
- OpenCL GPU float : 0.096 s