![]() |
|
|
可以将应用程序看成是众多相互依赖的任务的集合。将应用程序划分成多个独立的任务,并确定这些任务之间的相互依赖关系,这个过程被称为分解(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. 单线程与多线程耗时对比图
为什么多线程会比单线程更耗时呢?其原因就在于,线程启停以及线程上下文切换都会引起额外的开销,所以消耗的时间比单线程多。
为什么加锁后的三线程比两线程还慢呢?其原因也很简单,那把读写锁就是罪魁祸首。通过 Thread Viewer 也可以印证刚才的结果,实际情况并不是并行执行,反而成了串行执行,如图2:
图 2. 通过 Viewer 观察三线程运行情况
其中最下面那个线程是主线程,一个是 addx 线程,另外一个是 addy 线程,从图中不难看出,其他两个线程为串行执行。
通过数据分解来划分多线程,还存在另外一种方式,一个线程计算从1到 APPLE_MAX_VALUE/2 的值,另外一个线程计算从 APPLE_MAX_VALUE/2+1 到 APPLE_MAX_VALUE 的值,但本文会弃用这种模型,有兴趣的读者可以试一试。
在采用多线程方法设计程序时,如果产生的额外开销大于线程的工作任务,就没有并行的必要。线程并不是越多越好,软件线程的数量尽量能与硬件线程的数量相匹配。最好根据实际的需要,通过不断的调优,来确定线程数量的最佳值。
加锁与不加锁
针对加锁的三线程方案,由于两个线程访问的是 apple 的不同元素,根本没有加锁的必要,所以修改 apple 的数据结构(删除读写锁代码),通过不加锁来提高性能。
测试结果如下:
图 3. 加锁与不加锁耗时对比图
其结果再一次大跌眼镜,可能有些人就会越来越糊涂了,怎么不加锁的效率反而更低呢?将在针对 Cache 的优化一节中细细分析其具体原因。
在实际测试过程中,不加锁的三线程方案非常不稳定,有时所花费的时间相差4倍多。
要提高并行程序的性能,在设计时就需要在较少同步和较多同步之间寻求折中。同步太少会导致错误的结果,同步太多又会导致效率过低。尽量使用私有锁,降低锁的粒度。无锁设计既有优点也有缺点,无锁
|
Copyright @ 2006 天地合华科技 All Rights Reserved 北京天地合华科技有限责任公司 京ICP备09031756号 |
|
电话:010-51664188 51664189 51667681 邮箱:412414798@qq.com 地址:北京市海淀区阜成路42号中裕商务花园1号楼101室 |