Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreaded image processing in C++

I am working on a program which manipulates images of different sizes. Many of these manipulations read pixel data from an input and write to a separate output (e.g. blur). This is done on a per-pixel basis.

Such image mapulations are very stressful on the CPU. I would like to use multithreading to speed things up. How would I do this? I was thinking of creating one thread per row of pixels.

I have several requirements:

  • Executable size must be minimized. In other words, I can't use massive libraries. What's the most light-weight, portable threading library for C/C++?
  • Executable size must be minimized. I was thinking of having a function forEachRow(fp* ) which runs a thread for each row, or even a forEachPixel(fp* ) where fp operates on a single pixel in its own thread. Which is best?
    • Should I use normal functions or functors or functionoids or some lambda functions or ... something else?
    • Some operations use optimizations which require information from the previous pixel processed. This makes forEachRow favorable. Would using forEachPixel be better even considering this?
  • Would I need to lock my read-only and write-only arrays?
    • The input is only read from, but many operations require input from more than one pixel in the array.
    • The ouput is only written once per pixel.
  • Speed is also important (of course), but optimize executable size takes precedence.

Thanks.

More information on this topic for the curious: C++ Parallelization Libraries: OpenMP vs. Thread Building Blocks

like image 281
strager Avatar asked Nov 28 '08 19:11

strager


1 Answers

Your compiler doesn't support OpenMP. Another option is to use a library approach, both Intel's Threading Building Blocks and Microsoft Concurrency Runtime are available (VS 2010).

There is also a set of interfaces called the Parallel Pattern Library which are supported by both libraries and in these have a templated parallel_for library call. so instead of:

#pragma omp parallel for 
for (i=0; i < numPixels; i++) 
{ ...} 

you would write:

parallel_for(0,numPixels,1,ToGrayScale());

where ToGrayScale is a functor or pointer to function. (Note if your compiler supports lambda expressions which it likely doesn't you can inline the functor as a lambda expression).

parallel_for(0,numPixels,1,[&](int i)
{  
   pGrayScaleBitmap[i] = (unsigned BYTE)  
       (pRGBBitmap[i].red * 0.299 +  
        pRGBBitmap[i].green * 0.587 +  
        pRGBBitmap[i].blue * 0.114);  
});

-Rick

like image 84
Rick Avatar answered Oct 07 '22 04:10

Rick