我想通过使用pthreads并行化C中的嵌套循环(我有四个内核)。在循环内部,我只是为二维数组的每个索引分配一个值。

当我尝试将其与四个线程并行化时,它实际上使我的程序速度降低了3倍。我猜这是因为线程以某种方式相互阻塞。

这是要并行化的循环。

for ( i = 0; i < 1000; i++ )
      {
        for ( j = 0; j < 1000; j++ )
        {
          x[i][j] = 5.432;
        }
      }


我试图像这样并行化它。

void* assignFirstPart(void *val) {
     for ( i = 1; i < 500; i++ )
    {
      for ( j = 1; j < 500; j++ )
      {

        w[i][j] = 5.432;

      }
    }
}

void* assignSecondPart(void *val) {
     for ( ia = 500; ia < 1000; ia++ )
    {
      for ( ja = 500; ja < 1000; ja++ )
      {

        w[ia][ja] = 5.432;


      }
    }
}

void* assignThirdPart(void *val) {
     for ( ib = 1; ib < 1000; ib++ )
    {
      for ( jb = 500; jb < 1000; jb++ )
      {

        w[ib][jb] = 5.432;


      }
    }
}

void* assignFourthPart(void *val) {

     for ( ic = 500; ic < 1000; ic++ )
    {
      for ( jc = 500; jc < 1000; jc++ )
      {

        w[ic][jc] = 5.432;

      }
    }
}

success = pthread_create( &thread5, NULL, &assignFirstPart, NULL );
    if( success != 0 ) {
        printf("Couldn't create thread 1\n");
        return EXIT_FAILURE;
    }

success = pthread_create( &thread6, NULL, &assignSecondPart, NULL );
    if( success != 0 ) {
        printf("Couldn't create thread 2\n");
        return EXIT_FAILURE;
    }

    success = pthread_create( &thread7, NULL, &assignThirdPart, NULL );
    if( success != 0 ) {
        printf("Couldn't create thread 3\n");
        return EXIT_FAILURE;
    }

success = pthread_create( &thread8, NULL, &assignFourthPart, NULL );
    if( success != 0 ) {
        printf("Couldn't create thread 4\n");
        return EXIT_FAILURE;
    }

pthread_join( thread5, NULL );
pthread_join( thread6, NULL );
pthread_join( thread7, NULL );
pthread_join( thread8, NULL );


因此,正如我所说,以这种方式进行并行化会极大地减慢我的程序的速度,因此我可能正在做完全错误的事情。我很感谢任何建议。

最佳答案

assignThirdPart与前两个回调的索引重叠。您的循环条件毫无意义,您应该将最外层循环的1000次迭代分成3个部分,例如:

for ( i = 0; i < 333; i++ ) // thread 1
...
for ( i = 333; i < 666; i++ ) // thread 2
..
for ( i = 666; i < 1000; i++ ) // thread 3
...


同样,i = 1不等同于i = 0

话虽如此,这并不一定会提高性能。仅复制数据而不进行计算将使数据缓存在大多数计算机上成为瓶颈。如果将其拆分为3,则可能会干扰CPU最佳缓存使用的能力-这是高度特定于系统的。

在并行化过程中与内部迭代器配合使用时,您要做的是对要复制的整个区域进行分段-而不是使它线性化,而是在这里有一个线程副本,在那里有一个线程副本,这完全弄乱了缓存。请阅读Why does the order of the loops affect performance when iterating over a 2D array?

然后当然还有线程创建开销,在进行基准测试时也应考虑这些开销。

即使所有操作都正确完成,使用3个线程也不一定会更快。多线程并不是神奇的“始终具有最佳性能”的粉末,您可以将其撒在任意代码上以加快速度。高端线程CPU可以非常有效地处理1000个对齐的数据块,这非常有效。

关于c - 如何将嵌套循环与pthreads并行化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56630499/

10-11 16:46