2013-11-20 22 views
1

所以我有一个非常奇怪的C行多线程行为,只发生在我的Macbook上。我基本上是做矩阵乘法,出于某种原因,2个线程比1(duh)快得多,但3个线程不仅仅比2慢,而且慢于1!我获得的3个线程的值对于任何其他线程都保持稳定。OSX上奇怪的线程时间与C

在linux服务器上,我运行了这个程序,运行时间稳定得多,最多4个线程,然后它关闭。这里是时间和我的一些代码。

的Linux:

Threads  Seconds 
1  6.304504 
2  3.334440  No error. 
3  2.447981  No error. 
4  2.057114  No error. 
5  2.121951  No error. 
6  2.131267  No error. 
7  2.187199  No error. 
8  2.304021  No error. 
9  2.179180  No error. 
10  2.168700  No error. 

OSX:

Threads  Seconds 
1  1.228449 
2  0.791477  No error. 
3  1.799167  No error. 
4  1.870556  No error. 
5  2.004676  No error. 
6  1.934047  No error. 

内存分配:

int ** create_array(int rows, int columns){ 
    int **a; 
    a = malloc(rows * sizeof(int *)); 
    int i; 
    for (i = 0; i < rows; i++) 
     a[i] = malloc(columns * sizeof(int)); 
    return a; 
} 

线程创建:

void multiply_array(int**left, int**right, int**output, int threads){ 
    pthread_t *thread_list; 
    thread_list = malloc(threads * sizeof(pthread_t)); 
    x = 0; 
    y = 0; 
    int i; 
    for(i = 0; i < threads; i++){ 
     pthread_attr_t attr; 
     /* get the default attribute */ 
     pthread_attr_init(&attr); 
     /* create a new thread */ 
     pthread_create(&thread_list[i], &attr, worker, NULL); 
    } 
    for(i = 0; i < threads; i++){ 
     pthread_join(thread_list[i], NULL); 
    } 
    free(thread_list); 
} 

编辑:

每下面的评论的更多信息:

我被矩阵B(1000 * 500)乘以矩阵A(1200 * 1000),以获得矩阵C(1200 * 500)。

运行在2.7 GHz的英特尔酷睿i7(8核?)

编译命令:gcc的Lab4.c -O1 -Wall -o Lab4 -lpthread

我不能发布工人的代码,因为这是一个班,我担心在网上发布我的解决方案可能会有问题。实际上,每个工作人员接受输出数组中的一个单元格,并计算应该放入数组中的值。所有的数组都是全局变量。我添加了一个调试语句,它看起来像每个线程得到一个相当均匀的分布记录:

5  1.856814  No error. 
Thread exiting after processing 100001 records. 
Thread exiting after processing 99994 records. 
Thread exiting after processing 100002 records. 
Thread exiting after processing 100009 records. 
Thread exiting after processing 99994 records. 
Thread exiting after processing 100000 records. 
+4

有多大你的矩阵尺寸是多少?你有多少个CPU?你的“工人”是什么样的? – ams

+0

请发布完整的代码,您使用的编译器,编译器标志和您的CPU模型。然后,我们可能会提供帮助。 –

+0

这种事情的最常见原因是在你的线程中争夺一些资源。我的第一个猜测是编译器是矢量化的,并且你正在争夺矢量处理管道,但正如其他人所说的,我们需要看一个完整的例子来诊断。通常可以通过管理矢量管道而不是通过产生许多线程来做得更好。请注意,OS X在Accelerate中具有非常优化的矩阵乘法函数(并且BLAS版本为开源,可移植且可在大多数Linux发行版上使用)。 –

回答

1

看来,我是牺牲品false sharing。我选择使用全局变量来跟踪线程在矩阵中的位置,因此他们随机地遍历数组。分割每个线程要解决的问题使得事情进展速度明显加快,但我仍然没有获得更多线程的支持。

在Linux服务器:

Threads  Seconds 
1  6.400566 
2  3.253767  No error. 
3  2.235638  No error. 
4  1.982804  No error. 
5  1.803468  No error. 
6  1.493511  No error. 
7  1.445361  No error. 
8  1.308549  No error. 
9  1.336010  No error. 

上的MacBook Pro(英特尔酷睿i7):

Threads  Seconds 
1  1.214193 
2  0.584341  No error. 
3  0.414696  No error. 
4  0.500751  No error. 
5  0.493094  No error. 
6  0.612082  No error. 
7  0.479231  No error. 
8  0.539043  No error. 
9  0.539322  No error. 
+0

发布您的代码并告诉我们处理器正在使用什么。如果您使用带有两个内核和超线程的MacBook,那么难怪您不会超越两个线程。矩阵乘法主要是小心处理缓存的练习,所以多线程矩阵乘法很棘手。 – gnasher729