Існує задача обробки зображень, по пікселям обробляється у циклі.
Наприклад:
Використовуючи фрейморк Qt 5.4.0. Створив новий клас IncTask. Вхідні дані до потоку можливо передати тільки під час ініціалізації класу. А надалі використовувати приватні змінні.
Наприклад:
for (int i = 0; i < numPixels; i++, data += pixelSize) { if (output->colors == 3) { pixels[i * 4] = data[2 * colorSize]; pixels[i * 4 + 1] = data[1 * colorSize]; pixels[i * 4 + 2] = data[0]; } else { pixels[i * 4] = data[0]; pixels[i * 4 + 1] = data[0]; pixels[i * 4 + 2] = data[0]; } }З метою оптимізації розрахунку, спробую використати можливості багатопроцесорного комп'ютера.
Використовуючи фрейморк Qt 5.4.0. Створив новий клас IncTask. Вхідні дані до потоку можливо передати тільки під час ініціалізації класу. А надалі використовувати приватні змінні.
#include <QRunnable> #include <QThreadPool> class IncTask : public QRunnable { public: IncTask(int sstart, int scolorSize, int scolors, int spixelSize, int snumPixels, uchar *sdata, uchar *spixels) : start(sstart), colorSize(scolorSize), colors(scolors), pixelSize(spixelSize), numPixels(snumPixels), cdata(sdata), pixels(spixels) { } virtual void run() { qDebug() << "from thread start" << start << "end" << numPixels; uchar *data = cdata; data += (pixelSize*start); for (int i = start; i < numPixels; i++, data += pixelSize) { if (colors == 3) { pixels[i * 4] = data[2 * colorSize]; pixels[i * 4 + 1] = data[1 * colorSize]; pixels[i * 4 + 2] = data[0]; } else { pixels[i * 4] = data[0]; pixels[i * 4 + 1] = data[0]; pixels[i * 4 + 2] = data[0]; } } } virtual bool autoDelete(){ return true; } private: int start, colorSize, colors, pixelSize, numPixels; uchar *cdata; uchar *pixels; };
Надалі у тілі програми, створюємо екземпляри класу IncTask у кількості рівної максимальної кількості потоків у системі. У моєму випадку це 8.
qDebug() << "converting LIBRAW_IMAGE_RAW"; int numPixels = output->width * output->height; int colorSize = output->bits / 8; int pixelSize = output->colors * colorSize; pixels = new uchar[numPixels * 4]; uchar *data = output->data; timer.restart(); //split calculation to threads int maximumThreadCount = QThreadPool::globalInstance()->maxThreadCount(); qDebug() << "maximumThreadCount" << maximumThreadCount; int threadCount = maximumThreadCount; int perThread = numPixels / threadCount; for (int threadId = 0; threadId<threadCount; threadId++){ int start = perThread*threadId; int end = (perThread*(threadId + 1)); QThreadPool::globalInstance()->start(new IncTask(start, colorSize, output->colors, pixelSize, end, data, pixels)); } QThreadPool::globalInstance()->waitForDone(); qDebug() << "converting loop elapsed" << timer.elapsed() / 1000. << "sec.";
Таким чином на потоки розбито частини обробки всього зображення на потоки.
converting LIBRAW_IMAGE_RAW maximumThreadCount 8 from thread start 0 end 2263744 from thread start 2263744 end 4527488 from thread start 4527488 end 6791232 from thread start 6791232 end 9054976 from thread start 9054976 end 11318720 from thread start 11318720 end 13582464 from thread start 13582464 end 15846208 from thread start 15846208 end 18109952 converting loop elapsed 0.034 sec.
Дяка: QThreadPool - BlackBerry Native, code of QtRaw, Qt Multi Threaded Programming | Ynon Perek
Немає коментарів:
Дописати коментар