看网上很多关于多线程的讨论,但是感觉都没什么比较好的例子,于是我做了关于多线程与单线程直接性能比较,并且根据cpu core具体分析并附上代码,首先放上实验结果
时间用timeval 统计的可能有少许偏差不过不影响整体结果,clock多线程是有问题的
不阻塞的情况下
一共循环2100000000
例1.一个线程 5 seconds
例2.三个线程 绑定到同一个core(每个线程700000000次) 6 seconds
例3.七个线程 绑定到同一个core(每个线程300000000次) 6 seconds
例4.三个线程 分别绑定一个core(每个线程700000000次) 2 seconds
例5.七个线程 分别绑定一个core(每个线程300000000次) 1 seconds
阻塞情况,每个循环sleep1秒,一共21个循环
例6.一个线程 21 seconds
例7.七个线程 绑定到同一个core(每个线程3次) 3 seconds
例8.七个线程 分别绑定一个core(每个线程3次) 3 seconds
下面具体分析下阻塞与非阻塞,单core与多core的性能:
非阻塞:
单core:
1.非阻塞情况下,单个core将运算时间全部提供给一个计算线程没有额外性能损耗。单个事件处理时间短,且量大适合此方式。如 上述测试 例1 结果。
2.非阻塞情况下,单个core将运算时间提供给多个计算线程,但cpu core是按时间片调度线程的,一瞬间只能调度一个线程,所有线程实际上还是在串行直接,但多了线程调度的损耗。单个事件处理时间短,且量大用此方式不如单线充分利用cpu core。
如上述测试例2,例3结果。
多core:
如果多个core分别绑定线程,每个core运行自己的线程,也不会有线程调度损失。将运算分摊到各个线程上可以提高整体数据计算速度。
如上述测试 例4,例5结果
阻塞:
单core:
1.在阻塞情况下,单线程效率最低。每次都要等到函数阻塞结束才能继续运行。
如上述测试 例6.结果
2.在阻塞情况下,多线程可以有效利用cpu资源,因为一个线程阻塞的情况下cpu会去调度没有阻塞的线程。程序整体运行效率更高。如果阻塞时间较长性能可能接近多core绑定线程的方式。
如上述测试 例7.结果
多core:
1.多个core分别绑定线程,性能不差。如上述测试 例8.结果
但很多时候没必要因为性能和例7接近。
综上所述单纯说多线程性能好坏意义不大,还是要看使用场景,软件设计方案,及硬件情况来具体分析如何使用单线程或多线程。
void* callBackFun(void* count)
{
int c = (int)*((int*)count);
for(int i=0; i< c;++i)
{
}
}
void start2(int n = 1)
{
pthread_t g[10];
pthread_attr_t attr[10];
cpu_set_t cpu[10];
timeval start,end;
long dif_sec, dif_usec;
double duration;
//int count = 2100000000/n;
int count = 12/n;
if(n>1)
{
for(int i =0; i<n ;++i)
{
pthread_attr_init(attr+i);
CPU_ZERO(cpu+i);
CPU_SET(0, cpu+i);
if (0!=pthread_attr_setaffinity_np(attr+i, sizeof(cpu_set_t), cpu+i))
{
printf("set affinity failed");
return;
}
}
}
else
{
CPU_ZERO(cpu+0);
CPU_SET(0, cpu+0);
thread = pthread_self();
int s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), cpu+0);
if (0!=s)
{
printf("set affinity failed");
return;
}
}
gettimeofday(&start, NULL);
if(n>1)
{
for(int i =0; i<n ;++i)
{
pthread_create(g+i,attr+i,callBackFun,&count);
}
}
else
{
for(int i=0; i< count;++i)
{
}
}
if(n>1)
{
for(int i=0;i<n;++i)
{
int ret1 = pthread_join(g[i],
NULL);
}
}
gettimeofday(&end, NULL);
dif_sec = end.tv_sec - start.tv_sec;
dif_usec = end.tv_usec - start.tv_usec;
printf("running time for loop is %ldsec (%ld us) %d\n", dif_sec, dif_usec,count);
}