1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # include <upc.h> # include <upc_collective.h> shared [N/THREADS] int A[N]; shared int B[1]; // 方法 1: 用所有的线程来进行相同的计算 for(int i=0; i<N; ++i) sum += A; // 方法 2: 只用线程 0 来进行计算 if(UPC_THREAD==0) { for(int i=0; i<N; ++i) sum += A; } // 线程 3: 用所有的线程进行并行计算 upc_all_reduceI( B, A, UPC_ADD, N, N/THREADS, NULL, UPC_OUT_ALLSYNC ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # include <stdlib.h> # include <upc.h> # include <math.h> # include <upc_collective.h> # include <stdio.h> // 随机地生成一个点。如果这个点落在圆内返回 1,落在圆外面则返回 0。 int hit(void) { double x = drand48(); // 赋值给 x 一个随机值 double y = drand48(); // 赋值给 y 一个随机值 if(sqrt(x*x+y*y)<=1) return 1; else return 0; } int read_from_file() { return 1000; } shared int result; shared int samples_in[THREADS]; shared int from_file; shared int num_local_samples[THREADS]; int main(int argc, char **argv) { int N, samples; // 线程 0 从一个输入文件中读取要生成的样本点数。 if(MYTHREAD==0) { N = read_from_file(); from_file = N/THREADS; } // 用 upc_all_broadcast 变量 from_file 的值复制到其他线程。 upc_all_broadcast(num_local_samples, &from_file, sizeof(int), UPC_IN_ALLSYNC | UPC_OUT_ALLSYNC); samples = num_local_samples[MYTHREAD]; // 初始化一系列伪随机数 srand48(MYTHREAD); for (int i=0; i<samples; ++i) { // 每个线程生成一定数量的点,然后计算落在圆内点的数目。 samples_in[MYTHREAD] += hit(); } // 计算所有线程所产生的点中,有多少点落在圆内。 upc_all_reduceI (&result, samples_in, UPC_ADD, THREADS, 1,NULL, UPC_IN_ALLSYNC | UPC_OUT_ALLSYNC); if(MYTHREAD==0) { printf("pi: %f", 4.0 * result / N); } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # include <upc.h> # include <upc_collective.h> # include <stdio.h> # define BLKSIZE 5 # define N 5 # define PIVOT 5 shared [N] int srcA[N*THREADS]; // 输入数组 shared [N] int dstA[N*THREADS]; // 输出数组 // 数组 p 指定了输入数组要复制到的线程 shared int P[THREADS]; int main() { int i; srand(MYTHREAD); // 对数组 srcA 进行初始化 upc_forall(i=0; i<N*THREADS; i++; &srcA) srcA=i; // 确保 srcA 所有的元素均被初始化 upc_barrier; // 对该排列数组进行初始化,并确保下标 i (对应于线程 i)储存下一个线程的索引 P[MYTHREAD] = (MYTHREAD +1) % THREADS; // 每个线程根据数组 p 所指定的线程索引,复制其本地的 srcA 数组元素到数组 dstA upc_all_permute(dstA,srcA,P,N*sizeof(int),UPC_IN_ALLSYNC|UPC_OUT_ALLSYNC ); // 线程 0 输出数组 dstA 所有的元素 if(MYTHREAD==0) { for(i=0; i<N*THREADS; ++i) { printf("dstA[%d]=%d\n",i,dstA); } } upc_barrier; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # include <upc.h> # include <upc_collective.h> # define BLKSIZE 5 # define N 20 # define PIVOT 5 shared [BLKSIZE] int srcA[N]; // 输入数组 shared [BLKSIZE] int dstA[N]; // 输出数组 shared int LT[THREADS]; shared int GT[THREADS]; shared int PS_LT[THREADS]; shared int PS_GT[THREADS]; shared int MX[THREADS]; int main() { int i, lt_idx, gt_idx; srand(MYTHREAD); // 第一阶段: 初始化数组 srcA upc_forall(i=0; i<N; i++; &srcA) srcA = rand() % 10; upc_barrier; // 第二阶段: 每个线程计算满足不同条件的本地数组元素的数量 upc_forall(i=0; i<N; i++; &srcA) { if (srcA<=PIVOT) LT[MYTHREAD]++; else GT[MYTHREAD]++; } // 第三阶段: 计算每个线程的起始下标 upc_all_prefix_reduceI(PS_LT,LT,UPC_ADD,THREADS,1,NULL,UPC_IN_ALLSYNC|UPC_OUT_NOSYNC); upc_all_prefix_reduceI(PS_GT,GT,UPC_ADD,THREADS,1,NULL,UPC_IN_ALLSYNC|UPC_OUT_NOSYNC); upc_all_broadcast(MX, &PS_LT[THREADS-1], sizeof(int), UPC_IN_ALLSYNC|UPC_OUT_ALLSYNC); lt_idx = PS_LT[MYTHREAD] - LT[MYTHREAD]; gt_idx = MX[MYTHREAD] + PS_GT[MYTHREAD] - GT[MYTHREAD]; // 第四阶段:同步地复制每个元素到相应的区域 upc_forall(i=0; i<N; i++; &srcA) { if( srcA<=PIVOT) dstA[lt_idx++] = srcA; else dstA[gt_idx++] = srcA; } upc_barrier; } |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |