OpenMP中全局变量私有化的问题—H.264视频压缩

tangfangyong 2010-05-05 08:35:45
近期在做JM代码的并行化研究,由于是比较成型的代码,所以选用OpenMP技术,改动量较小且适合代码移植

现在发现了一个问题。我想在slice级做并行处理,一个线程处理一个slice。这样的话,对于数据来说,如何控制全局变量及共享变量是个很重要的问题。我将我遇到的问题写出来,希望能得到大家的指导和建议

视频压缩JM代码存在着大量的数据相关性,全局变量很多,最主要的想必就是 img这个结构体,其内部含有大约几百个variable,而且这些variable有些是数组有些是结构体还有些甚至是函数指针。

想法是:
1 让每个线程从主线程中拷贝全局变量到自己的线程栈中形成自己的私有变量,这里就有了点疑问。全局变量img很大,这样进行拷贝会不会对内存造成影响。
2 每个线程有了自己的私有变量,如何进行访问……这些值放在什么位置。
3 每个线程在执行过程中会调用大量的函数,这些函数都使用全局变量。在调用的时候进行值传递或者地址传递的时候会出现错误,如何解决呢???



全局变量有:
InputParameters inputs, *input = &inputs;
ImageParameters images, *img = &images;
StatParameters statistics, *stats = &statistics;
SNRParameters snrs, *snr = &snrs;
Decoders decoders, *decs=&decoders;
使用 threadprivate 声明上诉变量;

在一个主体函数中进行如下修改:

void code_a_picture(Picture *pic)
{
………
………
#pragma omp parallel for firstprivate lastprivate(img, stats,snr);
for (parallel_var=0;parallel_var <Total_Slice_num;parallel_var++)
{
if(!FmoSliceGroupCompletelyCoded (SliceGroup)) //
{
thread_num=omp_get_thread_num();//获取当前thread序号

printf("\n thread_num=%d\n",thread_num);

firstMBinSlice=parallel_var*input->slice_argument;//input->slice_argument=33;

codedMBnum=encode_one_slice (SliceGroup, pic, NumberOfCodedMBs,firstMBinSlice);//有写操作!!!

#pragma omp critical(NumberOfCodedMBs)
NumberOfCodedMBs +=codedMBnum;

//分配下一条带的起始位置,将最后一个处理的宏块写入 FirstMBInSlice[MAXSLICEGROUPIDS] 数组。
FmoSetLastMacroblockInSlice (img->current_mb_nr);

// Proceed to next slice
img->current_slice_nr++;
stats->bit_slice = 0;
}
}
……
……
}


在执行时发现错误,无法运行。经过查找得知是存在输出相关。而且每个线程中在执行过程都会遇到输出/写文件操作,处理起来难度有变大了。但是有个问题却一直困扰着我

在上文函数中有个函数调用encode_one_slice (SliceGroup, pic, NumberOfCodedMBs,firstMBinSlice),这个函数是这样定义的:
int encode_one_slice (int SliceGroupId, Picture *pic, int TotalCodedMBs,int firstMBinSlice)
{ int CurrentMbAddr;
CurrentMbAddr = firstMBinSlice;
img->current_mb_nr = CurrentMbAddr ;
/*********************************** TEST 1 ******************************************/
printf("\nimg->current_mb_nr=%d,Thread num: %d\n",img->current_mb_nr,omp_get_thread_num());
/*********************************** TEST 1 ******************************************/

/*********************************** TEST 2 ******************************************/
printf("\nimg->current_mb_nr=%d,Thread num: %d\n",img->current_mb_nr,omp_get_thread_num());
/*********************************** TEST 2 ******************************************/

/*********************************** TEST 3 ******************************************/
printf("\nimg->current_mb_nr=%d,Thread num: %d\n",img->current_mb_nr,omp_get_thread_num());
/*********************************** TEST 3 ******************************************/

…………
…………
}

我让函数输出当前 已经私有化的变量img->current_mb_nr值,按我的想法,一共有3个slice,这样就是用3个线程分别获得img->current_mb_nr为0,33,66.

但是test1 输出 img->current_mb_nr=0 Thread num=0; img->current_mb_nr=33 Thread num=1; img->current_mb_nr=66 Thread num=2;

但是test2 输出 img->current_mb_nr=33 Thread num=0; img->current_mb_nr=33 Thread num=1; img->current_mb_nr=33 Thread num=2;

但是test3 输出 img->current_mb_nr=66 Thread num=0; img->current_mb_nr=66 Thread num=1; img->current_mb_nr=66 Thread num=2;

可以看出img的值改变了,使用firstprivate按说应该不会影响其他的线程的值变化呀。希望高手给个解释

另外想问一下,使用parallel for之后,在并行区内去调用其他的函数A,B,C,函数ABC中的一些变量是不是当做私有变量处理……

谢谢……
...全文
456 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zz841215123 2011-12-09
  • 打赏
  • 举报
回复
请问这个楼主这个问题解决了吗?
westernkiller 2010-07-08
  • 打赏
  • 举报
回复
我也遇到类似问题了,不知道怎么解决。
intel_www 2010-05-06
  • 打赏
  • 举报
回复
“最主要的想必就是 img这个结构体”这句话不对。你的代码里img是一个指向结构体的指针,不是结构体。指针变量被设置成firstprivate只能使每个线程拥有一个指针变量的私有copy,这些私有copy仍然是指向同一个结构体的。所以结构体根本就没有得到保护。

并行区域里被调用函数的局部变量是私有变量。

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧