[gdal-dev] Best practices for concurrent writes with GDAL (was
RasterIO in paralel)
Even Rouault
even.rouault at mines-paris.org
Wed Feb 9 14:29:19 EST 2011
Le mercredi 09 février 2011 09:59:02, Antonio Valentino a écrit :
> Hi Francis,
>
> Il giorno Wed, 9 Feb 2011 09:38:49 +1100
>
> Francis Markham <fmarkham at gmail.com> ha scritto:
> > Is there a document anywhere specifying the best practices for
> > parallel writes to a GDAL raster? I have an embarrasingly parallel
> > problem that I would like to parallelise with MPI, but I'm not sure
> > what I am allowed to do in parallel. I would like to assign blocks
> > exclusively to worker threads to read and write concurrently, but I
> > am unsure how I might do this safely.
> >
> > Any suggestions would be greatly appreciated.
>
> Are you sure it is the best way to parallelize your problem?
> If you write tho the disk operation are in some way serialized.
> It is a common schema to have several worker processes/thread for CPU
> bound computations and a single IO processes/thread that collects all
> results and write them to disk.
>
> The IO process/thread int this case can also be designed to implement
> some optimization or caching mechanism that you could not apply at
> worker process level.
>
> With this schema you can bypass completely the problem of concurrent
> writes without loss of performance IMHO.
Yes I completely agree with the approach you suggest. Genuine concurrent
writing is likely not possible on the whole chain and will result in queing at
some point, for example at the OS level. (Unless you use some RAID, in which
case if the file is spread over multiple disks, it is perhaps possible to have
genuinge parallel writing of blocks of data of the same file.)
Nevertheless on GDAL side, you cannot safely use the WriteBlock() interface on
the same RasterBand object from different threads. For example, in the GeoTIFF
driver, for pixel-interleaved images, there is an optimization that doesn't
flush immediately the block to libtiff until another block is read/written. This
optimization is made so that, for a pixel-interleaved RGB image, you can fill
the R,G and B components of a of a block into memory without having to flush it
to disk at each time. The GTIFFDataset object has thus state variables to
maintain the current dirty block number and the associated buffer. If you try
to write from different threads, they will overwrite this dirty block number
and buffer, leading to chaos. I'd note that inside libtiff itself, there are
state variables too, mainly when compression codecs are involved (but possibly
also in the uncompressed case. I haven't checked). So if you want to use the
WriteBlock() interface, you have to a full code inspection of the driver code
to determine if it is safe to do so. And I'm afraid that the most popular
drivers aren't.
If you use the RasterIO() interface, you might encounter the issue that Frank
described about the flushes occuring potentially into a unappropriate thread. I
have identified in the past also a few potential race conditions. See
http://trac.osgeo.org/gdal/ticket/3225 and
http://trac.osgeo.org/gdal/ticket/3226. That last one is probably the
situation that Frank described. I'm not sure how/if it can be solved by
identifying an "appropriate" thread. This supposes that there's somehow a
"owner" thread of a dataset, which is not currently a requirement. What
happens if thread A opens a dataset, writes a few blocks (that go into the
block cache), then terminates and then thread B do other IO and close the
dataset... ?
Anyway, if you always use RasterIO() interface and not mix RasterIO() with
IReadBlock()/IWriteBlock(), I don't think that there are actually race
conditions (I will not guarantee it however. Race condition analysis is
terribly difficult) that could lead to the underlying IWriteBlock() to be called
from different threads concurrently (which is bad, see 2nd paragraph). So using
RasterIO() from different threads will lead to serialize the flushing of blocks
to the disk due to the use of the global cache mutex. And I doubt using
directly libtiff/libgeotiff will make it easier.
Best regards,
Even
More information about the gdal-dev
mailing list