我想通过使用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 );
因此,正如我所说,将其并行化会大大降低程序的速度,因此我可能正在做完全错误的事情。感谢您的任何建议。
答案 0 :(得分:1)
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个对齐的数据块。
答案 1 :(得分:0)
看起来您使用的是全局变量。
如果是这种情况,它们在与线程一起使用时会产生大量开销,并且会大大减慢速度。