Il threading OGR / GDAL comporta un utilizzo a basso core


13

Sto cercando di elaborare alcuni dati raster usando ogr / gdal e non riesco a ottenere il pieno utilizzo di tutti i core della mia macchina. Quando eseguo il processo solo su un singolo core, ottengo il 100% di utilizzo di quel core. Quando provo a dividere in multicore (nell'esempio seguente, tagliando gli offset x e mettendoli in coda), ottengo un utilizzo patetico su ciascuno dei miei 8 core. Sembra che aggiunge solo fino al 100% di utilizzo su ciascun core (ad es. 12,5% su ciascuno).

Ero preoccupato che utilizzare lo stesso datasource fosse il collo di bottiglia, ma poi ho duplicato il file raster sottostante per ciascun core ... e l'utilizzo del core è ancora una schifezza. Questo mi porta a credere che ogr o gdal si stiano comportando in qualche modo come una risorsa condivisa da strozzature ma non riesco a trovare nulla online a riguardo. Qualsiasi aiuto sarebbe molto apprezzato!

Questa è la funzione "helper" che viene eseguita all'interno di ogni thread di lavoro:

def find_pixels_intersect_helper(datasource, bounds_wkt, x_min, x_max):
    bounds = ogr.CreateGeometryFromWkt(bounds_wkt)
    rows_to_write = []
    for x_offset in range(x_min, x_max):
        for y_offset in range(datasource.RasterYSize):
            pxl_bounds_wkt = pix_to_wkt(datasource, x_offset, y_offset)
            pxl_bounds = ogr.CreateGeometryFromWkt(pxl_bounds_wkt)
            if pxl_bounds.Intersect(bounds):
                rows_to_write.append(['%s_%s' % (x_offset, y_offset), pxl_bounds.Centroid().ExportToWkt()])

Improbabile, ma hai verificato se la memoria è il collo di bottiglia?
lynxlynxlynx,

@lynxlynxlynx - yep. La memoria non è sicuramente il collo di bottiglia. Ho cercato di rintracciare questa cosa per tutto il giorno ... è abbastanza strano.
Max

È possibile che il driver raster in uso non sia progettato per essere chiamato da più di un thread alla volta. Riferimento: mail-archive.com/gdal-dev@lists.osgeo.org/msg07283.html
blah238

Risposte:


10

OK. È stato un giorno della mia vita che non tornerò mai più. Si scopre che il problema non era nel codice che ho pubblicato sopra. Va benissimo. Si è scoperto che questo era un caso di threading: thread vs. multiprocessing.Process.

Come sottolineato nella documentazione di Python :

Il pacchetto multiprocessore offre sia la concorrenza locale che remota, efficacemente aggirando il Global Interpreter Lock utilizzando sottoprocessi anziché thread. Per questo motivo, il modulo multiprocessore consente al programmatore di sfruttare appieno più processori su una determinata macchina

Pertanto, threading.Thread è per operazioni ad alta intensità di I / O, multiprocessing. Il processo è per operazioni ad alta intensità di CPU. Sono passato al multiprocessing. Il processo e tutto funziona alla grande.

Dai un'occhiata a questo tutorial per imparare a usare multiprocessing.Process


Stavo solo per suggerire che, non ero sicuro di quale implementazione (ci sono anche implementazioni di terze parti ) che stavi usando :) L'ho usata di recente per accelerare qui uno strumento per creare ombre pulite: Port "Producing Building Shadows" Avenue codice ad ArcGIS 10
blah238

+1 Stavo per pubblicare che dovresti inserire una parola nella mailing list di GDAL-dev; ma ora sono contento che tu non l'abbia fatto! Questo è stato eliminato per riferimento futuro.
MerseyViking,

FWIW (probabilmente non molto), ho letto da qualche parte che le persone stanno raccogliendo fondi per cercare di risolvere il problema del blocco dell'interprete globale (GIL). Penso che sarà per 3.x.
canisrufus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.