1. 目标:使用openmp实现图像滤波算法
| 给定一个输入图像,你的任务是将其划分为多个块,并使用多个进程对每个块进行滤波操作。 |
| 要求: |
| 1、使用分段并行结构和指令section来并行执行不同的计算步骤。 |
| 2、使用单线程指令single或master确保某些代码段只在单个线程中执行。 |
| 3、使用线程同步和阻塞机制来确保所有线程在进入下一步处理之前完成当前步骤的计算。 |
| 4、使用任务池并行化来处理滤波操作,并根据图像块的大小和数量选择静态任务或动态任务。 |
2. 思路
思路:
(1). 根据结果目标元素位置,判断出要计算的原始图像数据和卷积核的位置边界
(2). 输出图像每个元素的计算当做一个任务
(3). 如果对数据分块的处理:
| (a) 每个分块需要根据卷积核大小增加冗余数据空间,决定不采用分块模式。 |
| (b) 遍历分块分配任务仍需要放在single单线程内处理 |
| (c) 分块处理增加了代码复杂性,并无其他优点。决定不采用分快处理 |
3. 代码
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <omp.h> |
| |
| #define N 5 |
| #define FN 3 |
| |
| void print_matrixS(unsigned char* matrix, int rows, int cols) |
| { |
| printf("matrix:\n"); |
| for (size_t i = 0; i < rows; i++) |
| { |
| for (size_t j = 0; j < cols; j++) |
| printf("%d\t",matrix[i*cols+j]); |
| printf("\n"); |
| } |
| } |
| |
| void main() |
| { |
| unsigned char inPic[N][N] = {0}; |
| unsigned char outPic[N][N] = {0}; |
| unsigned char conv[FN][FN] = {0}; |
| double startTime,endTime; |
| |
| for(int i=0;i<N;i++) |
| { |
| for(int j=0;j<N;j++) |
| inPic[i][j] = rand()%256; |
| } |
| |
| for(int i=0;i<FN;i++) |
| { |
| for(int j=0;j<FN;j++) |
| conv[i][j] = 1; |
| } |
| omp_set_num_threads(10); |
| startTime = omp_get_wtime(); |
| |
| #pragma omp parallel proc_bind(close) |
| { |
| |
| #pragma omp single |
| { |
| |
| for(int i=0;i<N;i++) |
| { |
| for(int j=0;j<N;j++) |
| { |
| |
| #pragma omp task shared(conv) |
| { |
| |
| int up,down,left,right; |
| int half = FN/2; |
| left = (j - half)>=0 ? j-half : 0; |
| right = (j+half)<=N-1 ? j+half : N-1; |
| up = (i - half)>=0 ? i-half : 0; |
| down = (i+half)<=N-1 ? i+half : N-1; |
| int rNums,cNums; |
| rNums = down - up +1; |
| cNums = right - left +1; |
| |
| int rBegin,cBegin; |
| rBegin = FN/2-(i-up); |
| cBegin = FN/2-(j-left); |
| |
| int sum=0; |
| int weightSum = 0; |
| for(int r=up;r<=down;r++,rBegin++) |
| { |
| for(int c=left,cTempBegin=cBegin;c<=right;c++,cTempBegin++) |
| { |
| sum += inPic[r][c] * conv[rBegin][cTempBegin]; |
| weightSum += conv[rBegin][cTempBegin]; |
| } |
| } |
| double e = 1.0/(double)weightSum; |
| outPic[i][j] = (short)(sum*e); |
| } |
| } |
| } |
| } |
| } |
| #pragma omp taskwait |
| endTime = omp_get_wtime(); |
| printf("inPicSize %d useSec %f\n",N,(double)(endTime-startTime)); |
| print_matrixS((unsigned char*)inPic,N,N); |
| print_matrixS((unsigned char*)outPic,N,N); |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?