具有openmp并行功能的Qimage setPixel不起作用 [英] Qimage setPixel with openmp parallel for doesn't work

查看:271
本文介绍了具有openmp并行功能的Qimage setPixel不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码在没有并行性的情况下可以工作,但是当我添加并行编译指示时,它不起作用.此外,如果我不添加setPixel,则该代码可与编译指示omp并行完美地工作.因此,我想知道为什么当我尝试在新图像中设置像素时,并行性无法正常工作,并退出代码255的程序.该代码希望通过执行两次循环来更改图像,以使用高斯向量更改每个像素.如果无法理解某些问题,我会立即解决.

The code works without parallelism, but when I add pragma omp parallel, it doesn't work. Furthermore, the code works perfectly with pragma omp parallel if I don't add setPixel. So, I would like to know why the parallelism doesn't work properly and exits the program with code 255 when I try to set pixel in the new image. This code wants to change an image doing two loops to change every pixel using a Gauss vector. If something can't be understood I'll solve it inmediately.

for (h = 0; h < height; h++){
  QRgb* row = (QRgb*) result->scanLine(h);

  //#pragma omp parallel for schedule(dynamic) num_threads(cores) private (j, auxazul, auxrojo, auxverde) reduction(+:red,green,blue)
  for (w = 0; w < width; w++) {
      red=green=blue=0;

      minj = max((M-w),0);
      supj = min((width+M-w),N);
      for (j=minj; j<supj; j++){
          auxazul = azul [w-M+j][h];
          auxrojo = rojo [w-M+j][h];
          auxverde = verde [w-M+j][h];

          red += vectorGauss[j]*auxrojo;
          green += vectorGauss[j]*auxverde;
          blue += vectorGauss[j]*auxazul;
      }

      red /= 256; green /= 256; blue /= 256;
      //result->setPixel(w,h,QColor(red,green,blue).rgba());
      row[w] = QColor(red,green,blue).rgba();
  }

推荐答案

除了setPixel速度慢且线程不安全的注释外,当前您在编写结果时还存在竞争条件

Beside the comment that setPixel is slow and not thread safe, you currently have a race condition when writing the result

 row[w] = QColor(red,green,blue).rgba(); 

首先,您的代码很慢,因为您以内存效率低下的方式访问颜色矩阵.泵送螺纹会使该部分变差.假设您在每条扫描线上循环,您希望获得颜色矩阵的转置.哪个可以做:

Your code is slow in the first place because you are accessing your color matrices in a memory inefficient way. Pumping threads will make this part worse. Given that you loop on each scanline, you would like to have the transposee of your color matrices. Which allow you to do :

for (h = 0; h < height; h++){
  QRgb* row = (QRgb*) result->scanLine(h);

  auto azulscan = azul [h];
  auto rojoscan = rojo [h];
  auto verdescan = verde [h];

  for (w = 0; w < width; w++) {
      red=green=blue=0;
      minj = max((M-w),0);
      supj = min((width+M-w),N);
      for (j=minj; j<supj; j++){
          auto auxazul = azulscan [w-M+j];
          auto  auxrojo = rojoscan [w-M+j];
          auto auxverde = verdescan [w-M+j];

          red += vectorGauss[j]*auxrojo;
          green += vectorGauss[j]*auxverde;
          blue += vectorGauss[j]*auxazul;
      }
      row[w] = QColor(red,green,blue).rgba();
  }

}

我不太了解openmp,但是您希望每条扫描线只有一个线程,因此您的并行循环需要在第一个循环之上.像

I dont know openmp well but you want to have a single thread per scanline, so your parallel loop need to be above the first loop. Something like

#pragma omp parallel for whatever
for (h = 0; h < height; h++){
  QRgb* row;

  #pragma omp critical
  {
    row = = (QRgb*) result->scanLine(h);
  }

  .... 

}

另一点.您可以使用 std :: inner_product 在一行中计算颜色值一旦完成颜色输入的转置.

Another point. You can use std::inner_product to compute the color value in a single line once you have the transpose of the color inputs.

green = std::inner_product(&vectorGauss[minj], &vectorGauss[supj-1]+1, &verdescan[w-M+jmin], &verdescan[w-M+supj]+1)

这篇关于具有openmp并行功能的Qimage setPixel不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆