c - 为什么多线程更慢?
问题描述
实现了使用归并排序的1000000个节点的三个链表的多进程多线程实现。我比较了实现程序的实时性,但是多线程的方式比较慢。这是为什么?
process.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 );
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 sec\n", (double)(t2 - t1) / CLK_TCK);
printf("User time : %.5f sec\n", (double)mytms.tms_utime / CLK_TCK);
printf("System time : %.5f sec\n", (double)mytms.tms_stime / CLK_TCK);
实时结果:1.65
thread.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 sec\n", (double)(t2 - t1) / CLK_TCK);
printf("User time : %.5f sec\n", (double)mytms.tms_utime / CLK_TCK);
printf("System time : %.5f sec\n", (double)mytms.tms_stime / CLK_TCK);
结果实时 2.27
解决方案
为什么多线程更慢?
它是特定于处理器的,并且与内核数量、 CPU 缓存的组织、它们的缓存一致性、您的RAM相关。另请参阅https://www.phoronix.com/上的测试和基准测试;在 Intel Core i7 10700K 和 AMD Ryzen 9 3900X(价格接近)上不会一样。
它也是编译器和优化特定的。阅读Dragon 的书和一本关于计算机体系结构的好书。
它还取决于您特定的操作系统和特定的C 标准库(例如GNU glibc与musl-libc不同),并且可能具有与同一glibc 2.31
台计算机不同的性能。阅读高级 Linux 编程、pthreads(7)、nptl(7)、numa(7)、time(7)、madvise(2)、syscalls(2)glibc 2.30
您是否在最近的 Linux 上尝试过至少调用了最近的GCC 10 ? gcc -Wall -O3 -mtune=native
您可以在 Linux 上使用proc(5)然后使用hwinfo来查询您的硬件。
您可能对OpenCL、OpenMP或OpenACC感兴趣,并且应该阅读有关特定 C 编译器的优化选项的信息。对于最近的GCC,请参阅此。您甚至可以使用您的GCC 插件自定义您最近的 GCC以改进优化,您可以尝试最近的Clang或icc编译器。
另请参阅MILEPOST GCC项目和CTuning one。另请阅读这份报告草案。参加 ACM SIGPLAN和SIGOPS会议。联系您附近的计算机科学学者。
您可能可以在理解您的问题的答案的同时获得博士学位。
推荐阅读
- python - 在mysql数据库中插入“+”符号
- javascript - 生成数组Javascript的自定义对象
- django - 从 django 获取 url 的完整路径(不是 django 模板)
- c# - 从 ajax 调用 WCF 并收到此错误,加载失败:服务器响应状态为 500 (System.ServiceModel.ServiceActivationException)
- python-3.x - curl相当于python POST请求调用jenkins api
- elasticsearch - 用于在 json 文件中的字段中查找 id 的弹性搜索查询
- ios - 在iOS的应用程序委托中调用api是一种好方法吗?
- css - 使用 SCSS 或 SASS 时可以在类中设置 CSS @import 吗?同步融合示例
- python - 神经网络检测两幅图像之间的相机位置变化
- php - 来自服务器的意外响应。该文件可能已成功上传。签入媒体库或重新加载页面