OpenMP中全局变量私有化的问题—H.264视频压缩
近期在做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中的一些变量是不是当做私有变量处理……
谢谢……