2015-10-14 1 views
1

В Qt 5.5 для mac, я пытаюсь ускорить вычисление буфера изображения и его отображения с помощью QImage. Я использовал директивы openMP, но я понял, что это возится с дисплеем QImage.QImage и openmp при обновлении отображения изображения

Вот код:

int = 65535  
newPaintImage = new QImage(naxis1, naxis2, QImage::Format_ARGB32); 
#pragma omp parallel for 
for (int ii = 0; ii < nPixels; ++ii) 
{ 
    cred = (int) 255 * red16[ii]/range; 
    cgreen = (int) 255 * green16[ii]/range; 
    cblue = (int) 255 * blue16[ii]/range;  

    QRgb argb = qRgba(cred, cgreen, cblue, 255); 
    QRgb* rowData = (QRgb*) newPaintImage->scanLine(ii/naxis1); 
    rowData[ii%naxis1] = argb; 
} 
newPaintWidget = new PaintWidget(newPaintImage, naxis1, naxis2); 

В приведенной выше коде, nPixels является общим количеством пикселей в изображении и red16, green16 и blue16 являются 3 цветовым каналом моих изображений. Они имеют размер, равный nPixels. Значения naxis1 и naxis2 - это ширина и высота (в пикселях).

Обратите внимание на директиву pragma для параллелизации цикла for. Когда я использую его, я получаю скремблированные строки в моем изображении, и любое обновление изображения меняет результаты. Когда я не использую директиву pragma, так что используется только один поток, мое изображение прекрасное, как и ожидалось. Я изменяю и обновляю буфер с такой параллелизацией, и это беспорядок с дисплеем.

Есть ли лучший способ? Как убедиться, что мои потоки завершили задание, а затем обновили отображение в моем PaintEvent объекта Qt? Или что-то связано с тем, как QImage распределяется между потоками? ...

Благодарности

+1

Попробуйте добавить 'private (cred, cgreen, cblue)' в свою прагму OpenMP. Не уверен, что этого будет достаточно, но это определенно необходимо. – Gilles

+0

Чем больше я это читаю, тем больше я уверен, что '#pragma omp parallel для private (cred, cgreen, cblue)' должно быть достаточно, чтобы ваш код работал параллельно. Не уверен, что это будет быстрее, потому что ваш код в основном связан с памятью. – Gilles

+0

@gilles ОК, я просто попробовал его с # # pragma omp parallel для private (cred, cgreen, cblue) ', и у меня возникла ошибка компиляции: ' ошибка: ожидаемое имя переменной #pragma omp parallel для private (cred , cgreen, cblue) ' Я совершенно не осведомлен об этих директивах. Есть идеи? –

ответ

1

Благодаря предложению в комментарии, я установил ее. Предложение pragma private было необходимо для определения частных переменных для работы.

int cred2, cgreen2, cblue2 
#pragma omp parallel for private(cred2, cgreen2, cblue2) 
for (int ii = 0; ii < nPixels; ++ii) 
{ 
    cred2 = (int) 255 * red16[ii]/range; 
    cgreen2 = (int) 255 * green16[ii]/range; 
    cblue2 = (int) 255 * blue16[ii]/range; 
    QRgb argb = qRgba(cred2, cgreen2, cblue2, 255); 
    QRgb* rowData = (QRgb*) newPaintImage->scanLine(ii/naxis1); 
    rowData[ii%naxis1] = argb; 
} 
newPaintWidget = new PaintWidget(newPaintImage, naxis1, naxis2); 

И да, это значительно быстрее! Это используется с некоторыми сигналами/слотами QSlider, которые выполняют растяжение контраста. Здесь я упростил код. Фактически, range изменяется и не фиксируется и, например, red16[ii] - (red16[ii] - minValue), где minValue меняется с некоторыми QSliders.