I would not expect this to speed up for a variety of overlapping reasons: (1)
the underlying calls to the IlmImf library that reads OpenEXR are not fully
re-entrant/stateless, so there are mutex locks in OIIO read_scanlines and maybe
also within IlmImf (I'd need to check) to make sure the read/decodes don't
clobber each other; (2) depending on the compression type, scanlines may not be
stored "individually" but compressed in groups, so scanlines 14 and 15 aren't
necessarily separate reads or decompression tasks at all; (3) even if all the
scanlines were separately compressed and the read functions fully reentrant,
underneath it all there are disk reads that have to be ordered and don't
actually occur in parallel. Oh, and if you did read lots of scanlines at once,
OpenEXR and OIIO both have thread pools underneath that will parallelize the
decompression and data format conversions pretty nicely, so there won't be any
gain by doing an OMP loop additionally around that (that will "over-thread" and
probably slow you down).
But it's not hopeless. You can get a lot more performance by grouping the reads
in bigger batches. Ideally, you should read the whole image at once
float *floatPtr = line;
bool success = in->read_image(/*subimage=*/0, /*miplevel=*/0,
TypeDesc::FLOAT, floatPtr);
This will be the most efficient way to read the image -- it will maximally
exploit the underlying theading of both OIIO and the OpenEXR libraries, and
even the low-level disk reads that cannot be parallelized will at least be
large and sequential.
Then, if there is also pure computation (not I/O or library calls) that you
need to do on the resulting data, THAT can be parallelized by OMP or any other
method.
One more thing: the `#pragma omp parallel for` is just a compiler hint. It's
possible that the loop isn't being parallelized at all! The fact that inside
the loop you are calling in->read_scanlines -- which OMP won't know if it can
be safely parallelized or have order-dependent side effects -- may make it
throw up its hands and decline to parallelize the loop.
But OIIO comes with a parallel.h header that gives you reasonably decent
parallel-for that is guaranteed to parallelize using OIIO's internal thread
pool. So let's say that you not only want to read the image in, but you also
want to apply a gamma curve to the RGB values of the image. You could use it
this way:
#include <OpenImageIO/parallel.h>
// Step 1: read the image in the biggest chunk we can, trusting the
// underlying OIIO and OpenEXR parts to parallelize where possible.
bool success = in->read_image(/*subimage=*/0, /*miplevel=*/0,
TypeDesc::FLOAT, line);
// Step 2: do the pixel-by-pixel computation in parallel, using OIIO's
// parallel_for and thread pool:
OIIO::parallel_for (/*start=*/ 0, /*end=*/ height,
[&](int y){ // lambda function
float *floatPtr = line + linesize * y;
for (int x = 0; x < width, ++x, floatPtr += nchannels)
for (int c = 0; c < 3; ++c)
floatPtr[c] = powf(floatPtr[c], gamma);
});
That should work fairly well and is in no way dependent on your compiler's
implementation of OMP.
> On Oct 10, 2019, at 6:11 AM, [email protected] wrote:
>
> Hi,
>
> I try to read a scanline image in parallel with OpenMP like this:
>
> #pragma omp parallel for
> for (int y = 0; y < spec.height; y++)
> {
> float *floatPtr = line + linesize * y;
> bool success = in->read_scanlines(0, 0, y, y + 1, 0, 0, 3,
> TypeDesc::FLOAT, floatPtr);
> }
>
>
> I use VisualStudio 2015, /openmp is turend on. And it works with simple loops
> like multiply numbers or something like that. Unfortunately the
> read_scanlines() is not speed up as expected or at all. What's the problem
> with my approach?
> I read openExr files, it that maybe a problem?
>
> Thanks for any ideas.
>
> haggi
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
--
Larry Gritz
[email protected]
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org