C语言 为什么多线程速度较慢?



使用合并排序实现了三个具有 1000000 个节点的链表的多进程和多线程实现。 我比较了实现的程序的实时性,但多线程方法较慢。 为什么?

进程中的主要方法。

/* Insert nodes */
Node* tmp = NULL;   
int num;    
for( int i = 0; i < MAX; i++ )
{
fscanf(fread,"%d",&num);    
tmp = createNode(num , i ); 
insertNode( &list1.head, &list1.tail, tmp );
tmp = createNode(num , i ); 
insertNode( &list2.head, &list2.tail, tmp );    
tmp = createNode(num , i );
insertNode( &list3.head, &list3.tail, tmp );    
tmp = createNode(num , i ); 
}
free( tmp );    
fclose(fread);  
if ((t1 = times(&mytms)) == -1) {
perror("times 1");
exit(1);
}
pid1= fork();   
if(pid1==0){
mergeSort( &list1.head );   
file_output(&list1);    
freeAll( list1.head );
exit(1);    
}
pid2= fork();   
if(pid2==0){
mergeSort( &list2.head );   
file_output(&list2);    
freeAll( list2.head );  
exit(2);    
}
pid3 = fork();
if(pid3==0){
mergeSort( &list3.head );   
file_output(&list3);    
freeAll( list3.head );  
exit(3);    
}
wait(&status);  
wait(&status);
wait(&status);
if ((t2 = times(&mytms)) == -1) {   
perror("times 2");
exit(1);
}
printf("Real time : %.5f secn", (double)(t2 - t1) / CLK_TCK);
printf("User time : %.5f secn", (double)mytms.tms_utime / CLK_TCK);
printf("System time : %.5f secn", (double)mytms.tms_stime / CLK_TCK);

结果 实时 : 1.65

主线程.c

/* Insert nodes */
Node* tmp = NULL;   
int num;           
for( int i = 0; i < MAX; i++ )
{
fscanf(fread,"%d",&num); 
tmp = createNode(num , i ); 
insertNode( &list1.head, &list1.tail, tmp );  
tmp = createNode(num , i );  
insertNode( &list2.head, &list2.tail, tmp );  
tmp = createNode(num , i );  
insertNode( &list3.head, &list3.tail, tmp );  
}
free( tmp );
fclose(fread);  
if ((t1 = times(&mytms)) == -1) {
perror("times 1");
exit(1);
}
pthread_create( &t_id1, NULL, thread_func, &list1 );
pthread_create( &t_id2, NULL, thread_func, &list2 );
pthread_create( &t_id3, NULL, thread_func, &list3 );
pthread_join( t_id1, (void*)&status );
pthread_join( t_id2, (void*)&status );
pthread_join( t_id3, (void*)&status );
if ((t2 = times(&mytms)) == -1) {
perror("times 2");
exit(1);
}
printf("Real time : %.5f secn", (double)(t2 - t1) / CLK_TCK);
printf("User time : %.5f secn", (double)mytms.tms_utime / CLK_TCK);  
printf("System time : %.5f secn", (double)mytms.tms_stime / CLK_TCK);  

结果 实时 2.27

为什么多线程速度较慢?

它是特定于处理器的,并与内核数量、CPU 缓存的组织、缓存一致性、RAM 相关联。另请参阅 https://www.phoronix.com/上的测试和基准;在英特尔酷睿 i7 10700K 和 AMD 锐龙 9 3900X(价格接近(上不会相同。

它也既特定于编译器,又特定于优化。阅读龙的书和一本关于计算机体系结构的好书。

它还取决于您的特定操作系统和特定的 C 标准库(例如 GNU glibc 与 musl-libc 不同(,并且glibc 2.31的性能可能与同一台计算机上的glibc 2.30不同。ReadAdvanced Linux Programming, pthreads(7(, nptl(7(, numa(7(, time(7(, madvise(2(, syscalls(2(

您是否尝试过使用最近的Linux,并且至少将最近的GCC 10作为gcc -Wall -O3 -mtune=native调用?

你可以在 Linux 上使用 proc(5( 和 hwinfo 来查询你的硬件。

您可能对 OpenCL、OpenMP 或 OpenACC 感兴趣,您应该阅读有关特定 C 编译器的优化选项的信息。有关最近的 GCC,请参阅此处。您甚至可以使用GCC插件自定义最近的GCC以改进优化,并且可以尝试使用最近的Clang或icc编译器。

另见MILEPOST GCC项目和CTuning项目。另请阅读本报告草案。参加ACM SIGPLAN和SIGUPS会议。联系您附近的计算机科学学者。

您可能会在了解问题的答案的同时获得博士学位。

最新更新