我编写了一个程序来执行一些计算,然后合并结果。
我使用多线程并行计算。
在合并结果阶段,每个线程都会锁定全局数组,然后将单独的部分附加到它上面,并且会做一些额外的工作来消除重复。
我测试了一下,合并的开销随着线程数的增加而增加,而且速度出乎意料:
2线程:40,116,084(us)
6线程:511,791,532(us)
为什么:线程数增加时会发生什么?我该如何改变?
--------------------------斜线 ---------- -------------------------------------------
其实代码很简单,有伪代码:
typedef my_object{
长不;
整数计数;
双倍价值;
//其他的东西
} my_object_t;
静态 my_object_t** global_result_array; //大约十千个
静态 pthread_mutex_t global_lock;
void* thread_function(void* arg){
my_object_t** local_result;
int local_result_number;
诠释我;
my_object_t* ptr;
for(;;){
if( exit_condition ){ return NULL;}
if(merge_condition){
//开始记录时间点
pthread_mutex_lock( &global_lock);
for( i = local_result_number-1; i>=0 ;i++){
ptr = local_result[ i] ;
if( NULL == global_result_array[ ptr->no] ){
global_result_array[ ptr->no] = ptr; //第4步
}else{
global_result_array[ ptr->no] -> count += ptr->count; // 第 5 步
global_result_array[ ptr->no] -> value += ptr->value; // 第 6 步
}
}
pthread_mutex_unlock( &global_lock); // 记录的结束时间点
}else{
//做一些计算并产生部分和线程本地的结果,即local_result和local_result_number
}
}
}
如上,两个线程和六个线程的区别是第5步和第6步,我统计了第5步和第6步的执行顺序大约有几亿次。其他的都是一样的。
因此,在我看来,合并操作非常轻,尽管使用 2 线程或 6 线程,但它们都需要锁定和独占合并。
另一个令人吃惊的事情是:使用六线程时,第 4 步的成本飙升!这就是总成本暴涨的启动原因!
顺便说一句:测试服务器有两个 cpu,每个 cpu 有四个核心。