Multithreading 将OpenMP转换为TBB

Multithreading 将OpenMP转换为TBB,multithreading,parallel-processing,openmp,intel,tbb,Multithreading,Parallel Processing,Openmp,Intel,Tbb,我在将OpenMP代码转换为TBB时遇到一些困难。有人能帮我吗 我在OpenMP中有以下代码,结果非常好 # 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

我在将OpenMP代码转换为TBB时遇到一些困难。有人能帮我吗

我在OpenMP中有以下代码,结果非常好

# 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;
  }
}
}
}
#pragma omp并行\
共享(b、计数、计数最大值、g、r、x最大值、x最小值、y最大值、y最小值)\
私有(i,j,k,x,x1,x2,y,y1,y2)
{
#pragma omp for
对于(i=0;i//请注意OpenMP版本代码中的
private(i,j,k,x,x1,x2,y,y1,y2)
子句。此变量列表指定并行循环体中的private/local变量。但是,在TBB版本的代码中,这些变量中的许多被lambda捕获为引用(
[&]
)因此,代码是不正确的。它有争用,在我看来,从多个线程访问这些变量(缓存一致性开销和混乱循环索引)会导致速度变慢。因此,如果要修复代码,请将这些变量设置为局部变量,例如

tbb::parallel_for ( int(0), m, [&](int i)
{
double x, y, x1, x2, y1, y2; // !!!!
int j, k;                    // !!!!
for ( j = 0; j < n; j++)
{
  x = ( ( double ) (     j - 1 ) * x_max   
      + ( double ) ( m - j     ) * x_min ) 
      / ( double ) ( m     - 1 );
...
(int(0),m,[&](int i)的并行 { 双x,y,x1,x2,y1,y2;/!!!! int j,k;/!!!! 对于(j=0;j
注意OpenMP版本代码中的
私有(i,j,k,x,x1,x2,y,y1,y2)
子句。此变量列表指定并行循环体中的私有/局部变量。但是,在TBB版本的代码中,这些变量中的许多被lambda捕获为引用(
[&]
)因此,代码是不正确的。它有争用,在我看来,从多个线程访问这些变量(缓存一致性开销和混乱循环索引)会导致速度变慢。因此,如果要修复代码,请将这些变量设置为局部变量,例如

tbb::parallel_for ( int(0), m, [&](int i)
{
double x, y, x1, x2, y1, y2; // !!!!
int j, k;                    // !!!!
for ( j = 0; j < n; j++)
{
  x = ( ( double ) (     j - 1 ) * x_max   
      + ( double ) ( m - j     ) * x_min ) 
      / ( double ) ( m     - 1 );
...
(int(0),m,[&](int i)的并行 { 双x,y,x1,x2,y1,y2;/!!!! int j,k;/!!!! 对于(j=0;jTBB的默认分区器是
auto_partitioner
,它将递归工作细分到每个线程一次循环迭代的级别,这可能会导致巨大的开销。对于具有多个编译器的
工作共享构造,
的默认调度是
静态的
,因此您应该提供
parallel_for
算法与
static_partitioner
的单例实例在TBB中具有与OpenMP中相同的工作分布。我已更改了withtbb::parallel_for(TBB::blocked_range2d(0,m,0,n),[&](TBB::blocked_range2d s,static_partitioner()){for(int I=s.rows().begin();Iauto_partitioner
,它将递归工作细分到每个线程一个循环迭代的级别,这可能会导致巨大的开销。对于带有多个编译器的
工作共享结构,
的默认调度是
静态的
,因此您应该提供
pa将
算法与
静态分区器
的单例实例合并,使其在TBB中的工作分布与OpenMP中的工作分布相同。我已更改了withtbb::parallel_for(TBB::blocked_range2d(0,m,0,n),[&](TBB::blocked_range2d s,静态分区器()){for(int I=s.rows().begin();I