多线程就一定快吗?天真!
在《多线程排序》中介绍了多线程排序,似乎看起来多线程快了很多,然而多线程就一定更快吗?
为什么多线程就不一定快?
还是拿《多线程排序-真香!》中的程序举例,下面是各个线程数量的排序结果:
线程数 | 时间/s |
1 |
2.393644 |
2 |
1.367392 |
3 |
1.386448 |
4 |
1.036919 |
5 |
1.097992 |
6 |
1.218000 |
7 |
1.184615 |
8 |
1.176258 |
以上结果可能不准确,但是体现了一些变化趋势,即并不是线程数量越多越快,也不是单线程最快,而是线程数为4的时候最快。
为什么呢?
原因在于我的机器只有4个逻辑CPU,因此4是最合适的。为了不解释太多术语,简单解释一下。一个CPU就像一条流水线,会执行一系列指令,当你很多指定拆成4份(4线程)的时候,它是正好最合适的,少的时候,有一个闲着;而多了,就会存在抢占的情况。举个简单的例子,假设有4个水管可以出水,你现在去接水,那么你在每个水管下放一个桶去接水,自然要比只在一个水管下去接水要快的,但是如果你的水桶数量多于水管数,为了每个水桶都要有水,你在这个过程中就需要去切换水桶,每个水桶换一下,才能都接得上,而换的这个过程就像线程的上下文切换带来的开销。
因此,并不是线程越多越快,最合适的才最快。
单线程有时候反而更快
说到这你可能更会奇怪了,为什么单线程有时候反而会更快呢?还是拿接水为例,假设虽然有4个水管,但是你只有一个桶,因此你一个人从这个水管里一直接水是最快的;而如果你拿两个桶,这个接一点,又换一下,那个接一点,又换一下,中间显然有切换导致的中断,相同时间内单个桶接的比较多;这就是单核CPU妄图使用多线程提高效率或者每个线程都需要竞争同一把锁而实际可能会导致更慢的缘故。
举个绑核的例子:
$ taskset -c 1 taskset -c 1 ./multiThread 4
thread num:4
time 2.378558
我使用taskset将程序绑定在一个CPU上运行,可以看其时间足足是不绑核的时候的两倍有余。
什么叫都需要竞争呢?举个极端的例子,我们修改前面的工作线程代码如下:
/*比较线程,采用快速排序*/
void * workThread(void *arg)
{pthread_mutex_lock(&mutex);SortInfo *sortInfo = (SortInfo*)arg;long idx = sortInfo->startIdx;long num = sortInfo->num;qsort(&nums[idx],num,sizeof(long),compare);pthread_mutex_unlock(&mutex);pthread_barrier_wait(&b);return ((void*)0);
}
这里的例子比较极端,在排序的时候都给它们加上了锁(关于锁,后面会有文章进行更加详细的介绍。),即哪个线程拿到了锁,就可以继续工作,没有拿到的继续等待。使用完成后再释放。
在这样的情况下,看看4线程还有效果吗?
$ ./multiThread 4
thread num:4
time 2.480588
是最快的时候两倍多的时间!而且还比单个线程的时候要慢!!!
而另外一种情况,比如说从队列中取出数据,然后进行耗时处理,那么对取出数据的操作进行加锁是可行的,多线程的情况仍然能提高处理速度。但如果你仅仅是读取数据,那么单线程的情况可能会比多线程要快,因为它避免了线程上下文切换的开销。
扩展介绍-绑核
为什么要绑核?
充分利用CPU,减少CPU之间上下文切换
指定程序运行在指定CPU,便于区分
$ taskset -c 1 ./proName
将proName绑定在第二个核。
$ taskset -c 1-3 ./proName
绑定运行在第二个到第四个核。
$ taskset -p 3569
pid 3569's current affinity mask: f
查看进程3569当前运行在哪个核上。
mask f转为二进制即为1111,因此四个核都有运行。
当然除了命令行,还有函数接口可以使用,这里就不再扩展了。
如何查看机器的CPU数量
物理CPU个数,就是你实际CPU的个数:
$ cat /proc/cpuinfo | grep "physical id" | sort -u | wc -l
1
CPU物理核数,就是你的一个CPU上有多少个核心,现在很多CPU都是多核:
$ cat /proc/cpuinfo | grep "core id" | sort -u | wc -l
2
CPU逻辑核数,一颗物理CPU可以有多个物理内核,加上超线程技术,会让CPU看起来有很多个:
$ cat /proc/cpuinfo | grep "processor" | sort -u | wc -l
4
总结
线程上下文切换是有开销的,如果它的收益不能超过它的开销,那么使用多线程来提高效率将得不偿失。因此不要盲目推崇多线程。如果为了提高效率采用多线程,那么线程中最多应为逻辑CPU数。也就是说如果你的程序绑在一个核上或者你只有一个CPU一个核,那么采用多线程只能提高同时处理的能力,而不能提高处理效率。
https://www.yanbinghu.com/2019/12/25/46016.html
来源:公众号【编程珠玑】
作者:守望先生
ID:shouwangxiansheng
相关精彩推荐
多线程排序-真香!
我有一个问题,用了多线程后,两个问题有了现在
系统编程-文件读写这件小事
生成随机数的方式你选对了吗?
关注公众号【编程珠玑】,获取更多Linux/C/C++/数据结构与算法/计算机基础/工具等原创技术文章。后台免费获取经典电子书和视频资源
多线程就一定快吗?天真!相关推荐
- 【干货】python多进程和多线程谁更快
python多进程和多线程谁更快 python3.6 threading和multiprocessing 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很多都说python多进程更快,因为G ...
- 多线程一定比单线程快吗
多线程似乎一直给我们这样的印象就是多线程比单线程快,其实这是一个伪命题.事无绝对,多线程有时候确实比单线程快,但也有很多时候没有单线程那么快. 首先简单区分一下并发性(concurrency)和并行性 ...
- 和 杠精 聊Redis多线程 :(
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 周末被一位小同学憋的很窝火.他要和我探讨一下,redis到 ...
- Youtube-dl调用外部Aria2多线程加速下载
2019独角兽企业重金招聘Python工程师标准>>> youtube-dl是一个开源超级优秀好用的解析下载视频程序,大量视频网站都可以轻松解析下载,而且经常更新规则拥有大量的用户, ...
- 拜托!不要再问我是否了解多线程了好吗
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:腾讯推出高性能 RPC 开发框架 个人原创100W+访问量博客:点击前往,查看更多 来源:https://www ...
- Linux C :线程操作和线程同步的多线程并发编程
在这之前可以先看看这边文章了解线程概念,信号量,条件变量,死锁.管程等概念 https://blog.csdn.net/superSmart_Dong/article/details/11666837 ...
- [ js ] 可否用多线程的思路,解决大数量数据的性能问题?
js中也是有线程概念的,setTimeout,setInterval和ajax都是这样的例子,另起一个线程,时间上似乎是并行处理的.于是,我想是不是可以利用这个多线程的机制,优化一下大数量数据遍历时的 ...
- 同步异步多线程这三者关系,你能给面试官一个满意的回答吗?
前几天一位朋友去面试,面试官问了他同步,异步,多线程之间是什么关系,异步比同步高效在哪?多线程比单线程高效在哪?由于回答的不好,让我帮他捋一下,其实回答这个问题不难,难就难在只对别人说理论,而没有现杀 ...
- redis 多线程_唬人的Redis多线程,也就那么回事
不羡鸳鸯不羡仙,一行代码调半天.原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. 周末被一位小同学憋的很窝火. 他要和我探讨一下,redis到底是多线程的还是单线程的.这个 ...
最新文章
- mysql运行正确结果显示_以下代码执行的结果是()
- INS-20802 PRVF-9802 PRVF-5184 PRVF-5186 After Successful Upgradeto 11gR2 Grid Infrastructure
- python【蓝桥杯vip练习题库】ADV-188排列数
- 微信开发之获取OAuth2.0网页授权认证和获取用户信息进行关联(转:http://playxinz.iteye.com/blog/2249634)
- CodeFrist基础_迁移更新数据
- 2011-07-04 22:11 Jfreechart生成曲线图数据点显示数据值
- mysql增量备份保留策略_Mysql备份策略-完成备份+增量备份shell
- C/C++编程心得(二)
- 数据结构栈和队列_使您的列表更上一层楼:链接列表和队列数据结构
- SM3密码杂凑算法源码解析
- 反射机制在JDBC连接中的使用
- PYTHON博客记录0602
- VCLSkin皮肤在MDI窗体下的问题
- 16.2. jps - Java Virtual Machine Process Status Tool
- linux怎么编译python_linux 编译安装python3
- sql2005自动备份
- 将Subversion(SVN)日志记录导出到excel表格(理论windows和Linux通用)
- win10默认壁纸_仅4M!微软出品的壁纸软件,让桌面每天都不一样!
- 学霸的迷宫 - 广搜例题
- QQ群怎么快速封群,如何举报骗子QQ群可以使之封群?
热门文章
- 【AI工程论文解读】03-DevOps for AI-人工智能应用开发面临的挑战
- 使用百度UNIT搭建智能对话系统_订火车票实例
- 海信85U7G-PRO怎么样 有什么优缺点
- 计算机上根号是哪一个,电脑上怎么哪个键是数学中的开根号啊
- 制图大赛计算机二维绘图,第五届“高教杯”全国大学生先进成图技术与产品信息建模创新大赛 机械类 计算机绘图试卷.pdf...
- 中国最黑的十三个旅游景点
- java安装_Java编程语言的历史和未来
- 杭电oj2111(JAVA
- android 平板桌面,RUI平板桌面
- 扫福得福背后,支付宝AR红包的技术创新与故事