C 多线程1——pthread
一、多核时代
随着数字IC工艺的提升,单核性能越来越高,但随之来的是功率密度增大,芯片发热严重,要进一步提升性能,很自然会想到C多核。将计算任务分配到不同的cpu,最后将结果整合,完成多核并行。
二、C\C 的多线程
C提供了很方便的多线程库,最基本的是pthread库,C 里有thread库(调用起来更加方便),还有omp库(不必自己设置线程,已封装好),接下来将介绍C pthread库的应用实例,这些实例能够很方便移植到不同的应用中。omp库的实例可参看C openmp并行计算实例。
三、实例
pthread的实例参考了B站up主“正月点灯”的教学视频,讲得非常通俗易懂。
假设我们有一个数组arr[],长度为1亿,元素大小为0~4的随机数,我们需要计算它的和。
为此我们可以用两个线程,一个线程计算前5千万个元素之和,另一个线程计算后5千万个元素之和,最后两种相加。
顺便比较单线程的耗时,代码如下:
#include <stdio.h>#include <stdlib.h> #include <pthread.h>#include <time.h> #include <omp.h>#define MAX_SIZE 100000000int* arr;// 定义数据结构,用来传递参数typedef struct{ int first; int last; int result;}MY_ARGS;//定义函数,给多线程调用void* myfunc(void* args){ int i; int s=0; MY_ARGS* my_args = (MY_ARGS*) args; int first = my_args->first; int last = my_args->last; for(i=first;i<last;i ){ s=s arr[i]; } my_args -> result = s; return NULL;}int main(){ pthread_t th1; pthread_t th2; int i; arr = malloc(sizeof(int) * MAX_SIZE); int mid = MAX_SIZE/2; for(i=0;i<MAX_SIZE;i ){ arr[i]=rand()%5; } MY_ARGS args1 = {0,mid,0}; MY_ARGS args2 = {mid,MAX_SIZE,0}; //1.pthread running time clock_t start,end; start = clock(); pthread_create(&th1,NULL,myfunc,&args1); pthread_create(&th2,NULL,myfunc,&args2); pthread_join(th1,NULL); pthread_join(th2,NULL); int s = args1.result args2.result; end = clock(); printf("s = %d\n",s); printf("thread2 time : %ld\n",end-start); // 2.single running time start = clock(); s = 0; for(i=0;i<MAX_SIZE;i ){ s = s arr[i]; } end = clock(); printf("s = %d\n",s); printf("single time: %ld\n",end-start); // 3.omp running time start = clock(); s = 0; omp_set_num_threads(2); #pragma omp parallel { #pragma omp for reduction( :s) for(i=0;i<MAX_SIZE;i ){ s = s arr[i]; } } end = clock(); printf("s = %d\n",s); printf("omp time: %ld\n",end-start); return 0;}
代码比较了pthread2线程,单线程,omp2线程的结果:
可见两个线程,甚至还有可能变慢,可能的原因是这里的数据连续分布,gcc的优化已经很极致。如果两个任务比较独立,并行的效果会更明显。这里只是给个pthread应用的实例。
赞 (0)