如何正确结合#pragma omp task与simd实现矩形多指标并行计算
问题:正确结合OpenMP的for、simd与task指令实现矩形参数的函数级并行计算
我想要编写一个并行程序来计算多个矩形的周长、面积和对角线,计划采用函数级并行的方式实现——将周长、面积和对角线的计算过程并行化处理。目前我在程序中使用#pragma omp for将循环迭代分配给不同线程,并用#pragma omp simd实现计算向量化,但不知道如何正确结合代表非结构化函数级并行的#pragma omp task指令。我清楚当前代码的写法会对任务创建进行向量化,这对SIMD架构来说毫无意义,希望有人能解释如何正确使用#pragma omp for、simd和task指令,以下是我的代码:
#include<stdio.h> #include<stdlib.h> #include<omp.h> #include<math.h> #include<time.h> #define NUM_THREADS 4 /** * 该程序计算矩形的三个参数: * 1. 周长 ==> P = 2B + 2H * 2. 面积 ==> A = BH * 3. 对角线 ==> D² = B² + H² * * 必须使用以下4个指令:parallel, for, simd, task */ enum { BASE = 0, HEIGHT = 1, }; #pragma omp declare simd double compute_perimeter(double base, double height){ return (2 * base + 2 * height); } #pragma omp declare simd double compute_area(double base, double height){ return (base * height); } #pragma omp declare simd double compute_diagonal(double base, double height){ return (sqrt((base * base) + (height * height))); } double ** generate_rectangles(size_t n){ double ** rectangles = (double **)malloc(n * sizeof(double *)); for(size_t i = 0; i < n; ++i){ rectangles[i] = (double *)malloc(n * sizeof(double)); for(size_t j = 0; j < n; ++j) rectangles[i][j] = rand() % 100; } return rectangles; } void destroy_rectangles(double ** rectangles, size_t n){ for(size_t i = 0; i < n; ++i) free(rectangles[i]); free(rectangles); } int main(){ srand(time(NULL)); size_t n = rand() % 100000; double * perimeters = (double *)malloc(n * sizeof(double)); double * areas = (double *)malloc(n * sizeof(double)); double * diagonals = (double *)malloc(n * sizeof(double)); double ** rectangles = generate_rectangles(n); #pragma omp parallel for simd num_threads(NUM_THREADS) schedule(static) for(size_t i = 0; i < n; ++i){ #pragma omp task {perimeters[i] = compute_perimeter(rectangles[i][BASE], rectangles[i][HEIGHT]);} #pragma omp task {areas[i] = compute_area(rectangles[i][BASE], rectangles[i][HEIGHT]);} #pragma omp task {diagonals[i] = compute_diagonal(rectangles[i][BASE], rectangles[i][HEIGHT]);} } for(size_t i = 0; i < n; ++i) printf("矩形 %d:\n 底 = %lf, 高 = %lf, 周长 = %lf, 面积 = %lf, 对角线 = %lf\n\n", i, rectangles[i][BASE], rectangles[i][HEIGHT], perimeters[i], areas[i], diagonals[i]); free(perimeters); free(areas); free(diagonals); destroy_rectangles(rectangles, n); return 0; }
内容的提问来源于stack exchange,提问作者Matheus Sousa
相关产品推荐
相关产品推荐

