具有For循环和指针操作的OPENMP

时间:2014-10-23 21:42:12

标签: c++ pointers parallel-processing openmp directshow

上下文

我正在做一个directshow过滤器,它可以改变每个帧的对比度和亮度。指向第一帧的第一个像素的指针是:RGBTRIPLE *prgb = (RGBTRIPLE*) pData;

此外,int numPixels = cxImage * cyImage;是每帧的像素数。

循环

#pragma omp parallel for
for (int iPixel=0; iPixel < numPixels; iPixel++ ) {

    prgb->rgbtGreen = prgb->rgbtGreen * _contrastPower + _brightnessPower;
    prgb->rgbtBlue  = prgb->rgbtBlue  * _contrastPower + _brightnessPower;
    prgb->rgbtRed   = prgb->rgbtRed   * _contrastPower + _brightnessPower;  

    if(prgb->rgbtGreen>255) prgb->rgbtGreen = 255;
    if(prgb->rgbtBlue>255)  prgb->rgbtBlue  = 255;
    if(prgb->rgbtRed>255)   prgb->rgbtRed   = 255;


    prgb++;
}

问题

输出流无法识别。让我们说我们必须使用相同的指针来增加线程,当然它们最终会比赛并导致奇怪的问题。

此外,我尝试删除int iPixel并仅使用prgb *,但无法解决语法问题。

问题

使用指针操作时是否可以进行并行for循环?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:3)

问题是prgb是一个共享指针,并且在每个线程中递增它而没有任何数据保护会导致数据争用。相反,您的代码应该类似于:

#pragma omp parallel for schedule(static)
for (int iPixel=0; iPixel < numPixels; iPixel++ ) {
   RGBTRIPLE *ppixel = prgb + iPixel;

   ppixel->rgbtGreen = ppixel->rgbtGreen * _contrastPower + _brightnessPower;
   ppixel->rgbtBlue  = ppixel->rgbtBlue  * _contrastPower + _brightnessPower;
   ppixel->rgbtRed   = ppixel->rgbtRed   * _contrastPower + _brightnessPower;  

   if(ppixel->rgbtGreen>255) ppixel->rgbtGreen = 255;
   if(ppixel->rgbtBlue>255)  ppixel->rgbtBlue  = 255;
   if(ppixel->rgbtRed>255)   ppixel->rgbtRed   = 255;
}

该算法在现代CPU上受内存限制,因此如果图像数据不完全适合CPU缓存,则不要期望性能与线程数成线性比例。