Le filetage OGR / GDAL entraîne une faible utilisation du cœur

13

J'essaie de traiter certaines données raster à l'aide d'ogr / gdal et je n'arrive pas à obtenir la pleine utilisation de tous les cœurs de ma machine. Lorsque je n'exécute le processus que sur un seul cœur, j'obtiens une utilisation à 100% de ce cœur. Lorsque j'essaie de diviser en multicœurs (dans l'exemple ci-dessous, en découpant les décalages x et en les mettant dans une file d'attente), j'obtiens une utilisation pathétique sur chacun de mes 8 cœurs. Il semble que cela n'additionne que jusqu'à 100% d'utilisation sur chaque cœur (par exemple 12,5% sur chacun).

Je craignais que l'utilisation de la même source de données soit le goulot d'étranglement, mais j'ai ensuite dupliqué le fichier raster sous-jacent pour chaque cœur ... et l'utilisation du cœur est toujours de la merde. Cela m'amène à croire que l'ogr ou le gdal se comporte d'une manière ou d'une autre comme une ressource partagée goulot d'étranglement, mais je ne trouve rien en ligne à ce sujet. Toute aide serait très appréciée!

Il s'agit de la fonction "helper" qui s'exécute à l'intérieur de chaque thread Worker:

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()])
Max
la source
Peu probable, mais avez-vous vérifié si la mémoire est le goulot d'étranglement?
lynxlynxlynx
@lynxlynxlynx - oui. La mémoire n'est certainement pas le goulot d'étranglement. J'ai essayé de retrouver cette chose toute la journée ... c'est assez bizarre.
Max
Il se peut que le pilote raster que vous utilisez n'est tout simplement pas conçu pour être appelé à partir de plusieurs threads à la fois. Référence: mail-archive.com/[email protected]/msg07283.html
blah238

Réponses:

10

D'ACCORD. Ce fut un jour de ma vie que je ne reviendrai plus jamais. Il s'avère que le problème n'était pas dans le code que j'ai publié ci-dessus. C'est très bien. Il s'avère que c'était un cas de threading.Thread vs multiprocessing.Process.

Comme indiqué dans la documentation python :

Le package de multitraitement offre une concurrence à la fois locale et distante, en évitant efficacement le verrouillage d'interprète global en utilisant des sous-processus au lieu de threads. Pour cette raison, le module multiprocesseur permet au programmeur de tirer pleinement parti de plusieurs processeurs sur une machine donnée

Ainsi, threading.Thread est destiné aux opérations gourmandes en E / S, multiprocessing.Process est destiné aux opérations gourmandes en ressources processeur. Je suis passé au multiprocessing.Process et tout fonctionne très bien.

Consultez ce didacticiel pour savoir comment utiliser le multitraitement.

Max
la source
J'allais juste suggérer que, je ne savais pas quelle implémentation (il y a aussi des implémentations tierces ) que vous utilisiez :) J'ai récemment utilisé cela pour accélérer un outil de création d'ombres de construction soigné: Port «Produire des ombres de construction» Avenue code vers ArcGIS 10
blah238
+1 J'étais sur le point de poster que vous devriez avoir un mot sur la liste de diffusion GDAL-dev; mais je suis maintenant content que vous ne l'ayez pas fait! Cela a été évacué pour référence future.
MerseyViking
FWIW (probablement pas beaucoup), j'ai lu quelque part que les gens collectent des fonds pour essayer de résoudre le problème de verrouillage d'interprète global (GIL). Je pense que ce sera pour 3.x.
canisrufus