利用多线程计算元素数组的和
来源:互联网 发布:天涯明月刀数据异常 编辑:程序博客网 时间:2024/05/18 19:46
利用多线程计算元素数组的和
CS:APP有一章节讲的是多线程,里面有一个例子讲的是利用多线程可重入地计算数组元素的和。因为加法满足交换率,多线程计算数组元素的和再相加数学上是正确的。
首先一开始想写一个共享变量sum,所有线程都往sum上加,后来发现这样必须加锁,不然存在很严重的线程不安全问题,但是256个锁…画面太美不敢看,所以干脆写成可重入的函数了。
以下为代码:为了方便测量性能,我们令每一次加法内部做无用功浪费一点时间。所以编译起来有两个问题,一是不能开-O1,-O2,因为会把无用代码优化调,所以开-O0,二是一定要加-pthread。因为 pthread.h不是Linux默认静态库。
#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<time.h>#define LEN 2560000#define N 256#define TIMES 100#define WASTE 100int data[LEN];int sum[N];int ans;void init(){ ans=0; for (int i=0;i<N;i++) sum[i]=0; for (int i=0;i<LEN;i++) data[i]=1; return;}void dosomething(){ for (int i=0;i<WASTE;i++); return;}void* thread(void* vargp){ int k=((int*) vargp)[0]; int n=((int*) vargp)[1]; for (int i=k*LEN/n;i<(k+1)*LEN/n;i++) for (int j=0;j<TIMES;j++) { sum[k]+=data[i]; dosomething(); } return NULL;}int main(){ int* ptr; int var[N][2]; int cpe,cpe1; pthread_t tid[N]; time_t t1,t2; for (int n=1;n<=N;n=n*2) { time(&t1); init(); for (int i=0;i<n;i++) { var[i][0]=i; var[i][1]=n; pthread_create(&tid[i],NULL,thread,(void*)var[i]); } for (int i=0;i<n;i++) pthread_join(tid[i],NULL); for (int i=0;i<n;i++) ans+=sum[i]; if (ans!=LEN*TIMES) { printf("Wrong Answer!\n"); printf("ans=%d(but it should be %d!)\n",ans,LEN*TIMES); exit(1); } time(&t2); cpe=TIMES*LEN/((int)(t2-t1))/1000; if (n==1) cpe1=cpe; printf("%3d threads:time=%2d,CPE=%dK,acc rate=%.3f\n", n,(int)(t2-t1),cpe,((float)cpe)/cpe1); } exit(0);}
测试结果(CPE是一个相对参数,没有单位,大致指的是每一个元素处理的时间代价)
zzy@zzy-lenovo-g50-80:~/zzy/project/ICS/pthread$ ./psum
1 threads:time=64,CPE=4000K,acc rate=1.000
2 threads:time=34,CPE=7529K,acc rate=1.882
4 threads:time=29,CPE=8827K,acc rate=2.207
8 threads:time=27,CPE=9481K,acc rate=2.370
16 threads:time=27,CPE=9481K,acc rate=2.370
32 threads:time=27,CPE=9481K,acc rate=2.370
64 threads:time=26,CPE=9846K,acc rate=2.461
128 threads:time=27,CPE=9481K,acc rate=2.370
256 threads:time=26,CPE=9846K,acc rate=2.461
我们可以发现线程多于4个时候acc rate不再上升,也就是说很有可能zzy-lenovo-g50-80是一台四核的计算机。我们去网页上查了一查,发现是双核心四线程电脑,也就是说有超线程技术,所以可以同时处理四个线程,但是处理四线程因为超线程了,所以比双线程快不了多少,所以是双核心四线程计算机,与测量结果吻合。所以这个代码不仅可以求数组元素的和,还可以用来测量计算机的线程数。
- 利用多线程计算元素数组的和
- 计算数组元素和
- 用指针计算数组元素的和
- 利用自动索引计算数组元素的平方和
- 利用自动索引计算数组元素的平方和
- 利用自动索引计算数组元素的平方和
- 利用自动索引计算数组元素平方和
- 利用自动索引计算数组元素平方和
- 利用Map特性计算数组中元素重复出现的次数
- 数组指针和指针数组的区别,以及如何利用他们访问数组里面的元素
- 利用foreach和section遍历数组元素
- 求二维数组元素和的4种等价方式(利用二维数组和指针)
- 20170731 JAVA利用数组和循环比较数组元素的大小
- 计算数组中元素出现的百分比
- 计算一个整型数组的元素之和
- 计算数组元素个数和计算字符串数组元素个数方法
- 利用数组计算256的阶乘
- 计算一个整形数组里的连续元素和的最大值
- 120. Triangle
- Leetcode Count and Say
- 第九章 多态 和 接口
- 【42.59%】【codeforces 602A】Two Bases
- 第十章 异常和断言
- 利用多线程计算元素数组的和
- 53. Maximum Subarray Add to List QuestionEditorial Solution
- 分布式架构高可用架构篇_07_MySQL主从复制的配置(CentOS-6.7+MySQL-5.6)
- 第十一章 集合
- DSS遇到的问题
- 12.2 格栅
- 双击,弹出对话框退出App
- ngrok跑"半天" 端口失效
- 极光推送的集成步骤