注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Search的博客

不断学习中!

 
 
 

日志

 
 

Pthread求卷积  

2013-05-05 18:00:57|  分类: |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
//定义卷积核矩阵以及所要迭代的矩阵大小
#define KERNEL_SIZE 5
#define MATRIX_SIZE 256
#define THREAD_SIZE 4
#define ITERATOR_TIME 5

struct SonThread
{
pthread_t threadId;
int first_row;
int last_row;
//由于在进程的执行过程中需要经常的修改这两个变量,所以定义为volatile类型
volatile int isExit;
volatile int trigger;
};
//定义用于迭代的原始矩阵和保存中间结果的临时矩阵
double Old_Matrix[MATRIX_SIZE][MATRIX_SIZE];
double AfterIteratorMatrix[MATRIX_SIZE][MATRIX_SIZE];
//初始化卷积核矩阵
double KernelMatrix[KERNEL_SIZE][KERNEL_SIZE]=
{
{0.00,0.00,0.02,0.00,0.00},
{0.00,0.08,0.10,0.08,0.00},
{0.02,0.10,0.20,0.10,0.02},
{0.00,0.08,0.10,0.08,0.00},
{0.00,0.00,0.02,0.00,0.00}
};
int num=0;
struct SonThread threadList[THREAD_SIZE];
//计算经过迭代以后矩阵中坐标为(x,y)的点的值
double calcSum(int x,int y)
{
num++;
int i,j;
int center=KERNEL_SIZE/2;
double sum=0;
for(i=0; i<KERNEL_SIZE; i++)
{
for(j=0; j<KERNEL_SIZE; j++)
{
//求出真实坐标
int realX=x-center+i;
int realY=y-center+j;
//如果真是坐标越界则跳出循环,不进行计算
if(realX<0) continue;
if(realY<0) continue;
if(realX>=MATRIX_SIZE) continue;
if(realY>=MATRIX_SIZE) continue;
sum+=Old_Matrix[realX][realY]*KernelMatrix[i][j];
}
}
return sum;
}
void *thread_function(void *args)
{
struct SonThread *sonThread=(struct SonThread*)args;
int i,j;
while(!sonThread->isExit)
{
while(!sonThread->isExit&&!sonThread->trigger)
{
for(i=sonThread->first_row;i<=sonThread->last_row; i++)
{
for(j=0; j<MATRIX_SIZE; j++)
{
AfterIteratorMatrix[i][j]=calcSum(i,j);
}
}
//计算完成以后休眠,等待下次迭代操作的唤醒
usleep(32);
}
sonThread->trigger=0;
}
return NULL;
}
void control_iterator()
{
int i;
//唤醒休眠的线程
for(i=0;i<THREAD_SIZE;i++)
{
threadList[i].trigger=1;
}
//等待各个线程任务完成
for(i=0;i<THREAD_SIZE;i++)
{
while(threadList[i].trigger)
{
usleep(32);
}
}
memcpy(&Old_Matrix,&AfterIteratorMatrix,sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
}
//初始化要迭代的矩阵
int init_martix()
{
//分别将原矩阵和用来存储中间结果的矩阵初始化
bzero(&Old_Matrix,sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
bzero(&AfterIteratorMatrix,sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
bzero(&threadList,sizeof(struct SonThread)*THREAD_SIZE);
//用时间作为随机数种子
srand(time(NULL));
int i;
for(i=0; i<50; i++)
{
//生成50个随即的横纵坐标,初始化为255
int x=rand()%MATRIX_SIZE;
int y=rand()%MATRIX_SIZE;
Old_Matrix[x][y]=255;
}
int Matrix_Span=MATRIX_SIZE/THREAD_SIZE;
for(i=0; i<THREAD_SIZE; i++)
{
threadList[i].first_row=i*Matrix_Span;
threadList[i].last_row=(i+1)*Matrix_Span-1;
//考虑如果矩阵总行数不能够被线程总数整除,则最后一个进程之需要计算剩下的矩阵即可
if(i==THREAD_SIZE-1)
{
threadList[i].last_row=MATRIX_SIZE-1;
}
//开辟线程进行计算
pthread_create(&threadList[i].threadId,NULL,thread_function,&threadList[i]);
}
return 0;
}
void print_matrix()
{
int i,j;
for(i=0;i<MATRIX_SIZE;i++)
{
for(j=0;j<MATRIX_SIZE;j++)
{
printf("%7.2lf",Old_Matrix[i][j]);
}
printf("\n");
}
printf("\n");
}
void thread_finalize()
{
int i;
for(i=0;i<THREAD_SIZE;i++)
{
threadList[i].isExit=1;
pthread_join(threadList[i].threadId,NULL);
}
}
int main()
{
int result=init_martix();
if(result!=0)
{
printf("初始化过程失败\n");
exit(1);
}
int i,j;
for(i=1;i<20;i++)
{
printf("第%d次迭代\n",i);
for(j=0;j<ITERATOR_TIME;j++)
{
control_iterator();
}
print_matrix();
}
thread_finalize();
printf("*****%d******",num);
return 0;
}



  评论这张
 
阅读(159)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017