迷茫的开发
分类: C/C++
2017-12-08 18:45:51
该篇博文是在看了一些文献,说是使用条件变量+互斥量会比使用信号量效率高,而以前看书的时候,觉得其它们是信号量的特例,直觉觉得只是简化了使用。虽然很多场景也没有必要使用信号量的计数,但是正如《win32 多线程程序设计》提的,有些场景必须使用(在没有条件变量的情况下)。因此测一下,条件变量与信号量的并发性能对比。
多线程的循环队列见另外本人的另外一篇博文(http://blog.chinaunix.net/uid-28993794-id-5770897.html)
由于另外两个版本的循环队列,以及完整的测试程序,代码显得有点多就不贴了,描述一下测试场景!(从该篇文章可以看出队列的一个并发问题,但是不影响测试)
本文一共做了两次测试——结果看第二次测试就好了。第一次测试时是遇到了一点问题,以及有测试程序有BUG。第二次测试解决了此BUG,以及使用更大的数据来测试。
每个生产者和消费者都为一个线程,各自向队列中放、取一个消息(多个消息只能一个一个放)。生产者不能向满队列中放消息,消费者不能消费空消息。如果条件不满足,阻塞直到满足条件。
一个消息,简单定义为:
点击(此处)折叠或打开
环境 |
VMWare |
系统 |
Centos7_x64 |
CPU |
1 |
内存 |
1GB |
测试的思路为:每个生产者生产1万消息,调整生产者、消费者数量,缓冲区大小(循环队列大小),使并发数量达到最大。
但是测出来的数据有跳变的现象,经过分析,是总的测试时间太短导致误差。(数据没有实际参考意义就不贴了)。第二次将消息量改为了1亿,数据就比较相对比较稳定(条件变量还是有很大偏差,如果改为10亿偏差又会小很多,不过对于信号量来说执行时间过长。考虑到误差与对比的结果来说已经具有说服力,故还是采用1亿消息量进行测试)。
生产者、消费者两个,缓冲区1万,消息量1亿。原始数据3组(时间单位为us,速率单位:笔/ms):
序号 |
消息数量 |
生产时间 |
生产速率 |
消费时间 |
消费者速率 |
1 |
100000000 |
33586668 |
2977.372 |
36325765 |
2752.867008 |
|
100000000 |
34083701 |
2933.954 |
36323483 |
2753.039955 |
2 |
100000000 |
33605133 |
2975.736 |
36979767 |
2704.181451 |
|
100000000 |
35280315 |
2834.442 |
36589686 |
2733.010609 |
3 |
100000000 |
35826637 |
2791.219 |
37227484 |
2686.187442 |
|
100000000 |
34924632 |
2863.309 |
37674271 |
2654.331387 |
从表中计算的平均值等,与程序统计的一致,此处就不整理表格了。
从该表可以看出,至少数字没有太大的跳变了,因此用该方法统计几组数据:
生产速率 |
消费者速率 |
差值 |
高多少 |
偏差 |
2903.37 |
2718.52 |
184.85 |
6.80% |
1.34% |
2955.5 |
2752.95 |
202.55 |
7.36% |
9.66% |
2826.8 |
2670.16 |
156.64 |
5.87% |
-12.57% |
2993.23 |
2783.77 |
209.46 |
7.52% |
12.14% |
2924.19 |
2758.67 |
165.52 |
6.00% |
-10.58% |
2950.77 |
2721.45 |
229.32 |
8.43% |
25.59% |
2874.57 |
2757.5 |
117.07 |
4.25% |
-36.72% |
2918.347 |
2737.57429 |
180.7728571 |
6.71% |
|
|
|
直接算平均值 |
6.60% |
|
该表统计了生产速率和消费速率的关系——考虑了测试中的误差。
测试案例都一样:
生产速率 |
消费者速率 |
差值 |
高多少 |
844.108 |
844.289 |
-0.181 |
-0.02% |
843.285 |
844.689 |
-1.404 |
-0.17% |
851.864 |
851.705 |
0.159 |
0.02% |
841.78 |
838.346 |
3.434 |
0.41% |
836.372 |
835.402 |
0.97 |
0.12% |
从上面可以看出信号量的误差要小很多。
信号量的误差较小,因此增加测试10亿部分,生产者和消费者速率分别是:2856.48、2675.15。比开始测出的数据还要小,因此将缓冲区增大到100万。结果分别是:2827.63、2679.1
从这里可以看出,似乎增大测试量,生产者和消费者的速率是在靠近的。但是无法证明。
说明:
测试时,CPU会持续100%,内存使用1万缓冲区0.1%,使用100万缓冲区4%。时间可以从表中看出。
信号量速率比条件变量小很多(1/3)(信号量根据操作系统中标准的PV操作来实现的。)
同样的测试程序,且生产者和消费者都是做一次memcpy,信号量的生产者和消费者速率会更匹配一点。