J'ai quelques difficultés à convertir un code OpenMP en TBB. Est-ce que quelqu'un peut m'aider?Conversion d'OpenMP en TBB
J'ai le code suivant dans OpenMP, où les résultats sont assez bons
# pragma omp parallel \
shared (b, count, count_max, g, r, x_max, x_min, y_max, y_min) \
private (i, j, k, x, x1, x2, y, y1, y2)
{
# pragma omp for
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
//cout << omp_get_thread_num() << " thread\n";
x = ((double) ( j - 1) * x_max
+ (double) (m - j ) * x_min)
/(double) (m - 1);
y = ((double) ( i - 1) * y_max
+ (double) (n - i ) * y_min)
/(double) (n - 1);
count[i][j] = 0;
x1 = x;
y1 = y;
for (k = 1; k <= count_max; k++)
{
x2 = x1 * x1 - y1 * y1 + x;
y2 = 2 * x1 * y1 + y;
if (x2 < -2.0 || 2.0 < x2 || y2 < -2.0 || 2.0 < y2)
{
count[i][j] = k;
break;
}
x1 = x2;
y1 = y2;
}
if ((count[i][j] % 2) == 1)
{
r[i][j] = 255;
g[i][j] = 255;
b[i][j] = 255;
}
else
{
c = (int) (255.0 * sqrt (sqrt (sqrt (
((double) (count[i][j])/(double) (count_max))))));
r[i][j] = 3 * c/5;
g[i][j] = 3 * c/5;
b[i][j] = c;
}
}
}
}
Et la version TBB est 10 fois plus lent que OpenMP
le code de TBB est:
tbb::parallel_for (int(0), m, [&](int i)
{
for (j = 0; j < n; j++)
{
x = ((double) ( j - 1) * x_max
+ (double) (m - j ) * x_min)
/(double) (m - 1);
y = ((double) ( i - 1) * y_max
+ (double) (n - i ) * y_min)
/(double) (n - 1);
count[i][j] = 0;
x1 = x;
y1 = y;
for (k = 1; k <= count_max; k++)
{
x2 = x1 * x1 - y1 * y1 + x;
y2 = 2 * x1 * y1 + y;
if (x2 < -2.0 || 2.0 < x2 || y2 < -2.0 || 2.0 < y2)
{
count[i][j] = k;
break;
}
x1 = x2;
y1 = y2;
}
if ((count[i][j] % 2) == 1)
{
r[i][j] = 255;
g[i][j] = 255;
b[i][j] = 255;
}
else
{
c = (int) (255.0 * sqrt (sqrt (sqrt (
((double) (count[i][j])/(double) (count_max))))));
r[i][j] = 3 * c/5;
g[i][j] = 3 * c/5;
b[i][j] = c;
}
}
});
Le partitionneur par défaut de TBB est 'auto_partitioner', qui effectue la subdivision de travail récursif à un niveau d'une itération de la boucle par fil, ce qui pourrait entraîner une tête énorme. La planification par défaut de la construction 'for' de partage de travail avec de nombreux compilateurs est' static', vous devez donc fournir l'algorithme 'parallel_for' avec l'instance singleton de' static_partitioner' pour avoir la même distribution de travail dans TBB que dans OpenMP. –
J'ai changé le parallel_for avec –
TBB :: parallel_for (TBB :: blocked_range2d (0, m, 0, n) \t, [&] (TBB :: blocked_range2d s, static_partitioner()) { \t pour (int i = s.rows(). begin(); i