留言反馈 用户登录 用户注册
 首页 >> 最好用还可以终身使用的永久财泉免费进销存软件免费下载官方网站 >> 技术知识库 >> 正文

利用多核多线程进行程序优化

序,就必须把自己的思维从线性模型中拉出来,重新审视整个处理流程,从头到尾梳理一遍,将能够并行执行的部分识别出来。

可以将应用程序看成是众多相互依赖的任务的集合。将应用程序划分成多个独立的任务,并确定这些任务之间的相互依赖关系,这个过程被称为分解(Decomosition)。分解问题的方式主要有三种:任务分解、数据分解和数据流分解。关于这部分的详细资料,请参看参考资料一。

仔细分析样例程序,运用任务分解的方法 ,不难发现计算 apple 的值和计算 orange 的值,属于完全不相关的两个操作,因此可以并行。

改造后的两线程程序:

清单 2. 两线程程序
void* add(void* x)
{
for(sum=0;suma += sum;
((struct apple *)x)->b += sum;
}

return NULL;
}

int main (int argc, const char * argv[]) {
// insert code here...
struct apple test;
struct orange test1={{0},{0}};
pthread_t ThreadA;

pthread_create(&ThreadA,NULL,add,&test);

for(index=0;indexrwLock);
for(sum=0;suma += sum;
}
pthread_rwlock_unlock(&((struct apple *)x)->rwLock);

return NULL;
}

void* addy(void* y)
{
pthread_rwlock_wrlock(&((struct apple *)y)->rwLock);
for(sum=0;sumb += sum;
}
pthread_rwlock_unlock(&((struct apple *)y)->rwLock);

return NULL;
}

int main (int argc, const char * argv[]) {
// insert code here...
struct apple test;
struct orange test1={{0},{0}};
pthread_t ThreadA,ThreadB;

pthread_create(&ThreadA,NULL,addx,&test);
pthread_create(&ThreadB,NULL,addy,&test);

for(index=0;index<ORANGE_MAX_VALUE;index++)
{
sum+=test1.a[index]+test1.b[index];
}

pthread_join(ThreadA,NULL);
pthread_join(ThreadB,NULL);

return 0;
}

这样改造后,真的能达到我们想要的效果吗?通过 K-Best 测量方法,其结果让我们大失所望,如下图:

图 1. 单线程与多线程耗时对比图
null

为什么多线程会比单线程更耗时呢?其原因就在于,线程启停以及线程上下文切换都会引起额外的开销,所以消耗的时间比单线程多。

为什么加锁后的三线程比两线程还慢呢?其原因也很简单,那把读写锁就是罪魁祸首。通过 Thread Viewer 也可以印证刚才的结果,实际情况并不是并行执行,反而成了串行执行,如图2:

图 2. 通过 Viewer 观察三线程运行情况
null

其中最下面那个线程是主线程,一个是 addx 线程,另外一个是 addy 线程,从图中不难看出,其他两个线程为串行执行。

通过数据分解来划分多线程,还存在另外一种方式,一个线程计算从1到 APPLE_MAX_VALUE/2 的值,另外一个线程计算从 APPLE_MAX_VALUE/2+1 到 APPLE_MAX_VALUE 的值,但本文会弃用这种模型,有兴趣的读者可以试一试。

在采用多线程方法设计程序时,如果产生的额外开销大于线程的工作任务,就没有并行的必要。线程并不是越多越好,软件线程的数量尽量能与硬件线程的数量相匹配。最好根据实际的需要,通过不断的调优,来确定线程数量的最佳值。

加锁与不加锁

针对加锁的三线程方案,由于两个线程访问的是 apple 的不同元素,根本没有加锁的必要,所以修改 apple 的数据结构(删除读写锁代码),通过不加锁来提高性能。

测试结果如下:

图 3. 加锁与不加锁耗时对比图
null

其结果再一次大跌眼镜,可能有些人就会越来越糊涂了,怎么不加锁的效率反而更低呢?将在针对 Cache 的优化一节中细细分析其具体原因。

在实际测试过程中,不加锁的三线程方案非常不稳定,有时所花费的时间相差4倍多。

要提高并行程序的性能,在设计时就需要在较少同步和较多同步之间寻求折中。同步太少会导致错误的结果,同步太多又会导致效率过低。尽量使用私有锁,降低锁的粒度。无锁设计既有优点也有缺点,无锁

9 7 3 1 2 3 4 4 8 :
软件开发网 天天精品下载 泡泡网高速下载 免费金山毒霸下载 微山财泉免费进销存 北京海淀科技委 北京产权交易所 北京软件行业协会
遵化财泉代理 IT专家网 信息化it168 比特网 计算机与IT行业网群 国家863中部软件园 国家工业信息化部 中国中小企业协会
中国软件外包网 中国计算机用户 中国计算机报 中国双软认定网 中国软件评测中心 中国软件行业协会 新浪财泉免费进销存 逊色资源站免费进销存
保定供求网免费进销存 阿里伯乐 管家婆软件 google财泉免费进销存 百度财泉免费进销存 慧聪财泉免费进销存 优酷视频免费进销存 天空软件商城免费进销存
soso财泉免费进销存 免费服装进销存软件 华军软件园免费进销存 天空软件站免费进销存 中国软件网免费进销存 绿色软件联盟免费进销存 中关村在线免费进销存 财泉软件免费进销存
Copyright @ 2006 天地合华科技 All Rights Reserved 北京天地合华科技有限责任公司 京ICP备09031756号
电话:010-51664188 51664189 51667681 邮箱:412414798@qq.com 地址:北京市海淀区阜成路42号中裕商务花园1号楼101室