Please activate JavaScript!
Please install Adobe Flash Player, click here for download

arcAKTUELL 1.2013 - Leben in der Stadt

46 T I P P S U N D T R I C K S Bei der Anwendung von Geoverarbeitungswerkzeugen stellt man im- mer wieder fest, dass nicht alle Systemressourcen (CPU, RAM, …) voll- ständig ausgeschöpft werden. Während man dies auf der einen Seite begrüßt, weil man in der Zwischenzeit auch noch andere Dinge am Sys- tem erledigen kann, wünscht man sich vor allem bei Prozessen mit sehr langen Laufzeiten aufgrund von großen Datenmengen oder sehr vielen einzelnen Datensätzen eher eine Beschleunigung der Verarbeitung durch die Nutzung aller verfügbarer Ressourcen. Die in Python integrierten Module thread und multiprocessing bieten ohne zusätzliche Installationen die Möglichkeit, Geoverarbeitungspro- zesse durch Parallelisierung zu beschleunigen, wobei der Grad der Be- schleunigung sehr stark von den einzelnen Aufgabenstellungen ab- hängt. Dabei ist zu beachten, dass mit der Parallelisierung ein zusätzlicher zeitlicher Overhead verbunden ist. Er resultiert zum einen aus dem Entwicklungsaufwand – in der Regel mit einem „Trial and error“-Szenario, bis die optimale Partitionierung gefunden ist – und zum anderen aus zusätzlichem Rechenaufwand. Letzter entsteht da- durch, dass die zu verarbeitenden Daten für die einzelnen Jobs vorkon- fektioniert und am Schluss die Teilergebnisse der einzelnen Prozesse wieder zu einem Gesamtresultat zusammengeführt werden müssen. Dazu kommt, dass bei jedem neuen Prozess („out-of-process“) die Geoverarbeitungsumgebung neu initialisiert werden muss, was bei einer Verarbeitung „in-process“ nicht erforderlich ist. Dieser Overhead kann nur dadurch kompensiert werden, dass die Zeitersparnis durch die Pa- rallelisierung den Aufwand der Konfektionierung und Initialisierung mehr als nur ausgleicht und der Entwicklungsaufwand durch die häufi- ge, am besten regelmäßige Verwendung der Geoverarbeitungswerk- zeuge gerechtfertigt werden kann. Was die Teilergebnisse einzelner Prozesse betrifft, so ist die Nutzung ei- ner gemeinsamen prozessübergreifenden Geodatabase im Allgemei- nen nicht möglich. Beim Anlegen von neuen Tabellen in der Geodata- base wird sie von einem der Prozesse exklusiv gesperrt (schema lock), sodass andere Prozesse an dieser Stelle scheitern. In diesem Fall muss in einem temporären Verzeichnis für jeden Prozess eine prozesseigene File-Geodatabase erzeugt werden. Nur wenn eine derartige Schema- änderung in der Datenbank nicht erforderlich ist und Daten von paral- lelen Prozessen in vorhandene Tabellen geschrieben werden, ist eine Multiuser- bzw. ArcSDE Geodatabase nutzbar. Zwischenergebnisse soll- ten aus Performancegründen immer in einer „In_memory“-Geodata- base zwischengespeichert werden. Um Out-of-Memory-Probleme zu vermeiden, sollte an jedem Prozessende die „In_memory“-Geodata- base explizit gelöscht werden. Löschen einer „In_memory“-Geodatabase: arcpy.Delete_management(„in_memory“) Wie schon erwähnt funktioniert das Multiprocessing in ArcGIS nur out- of-process. Das bedingt, dass bei den Eigenschaften eines Skript-Tools, das im referenzierten Python-Skript das Modul multiprocessing nutzt, nicht der Haken bei „Run Python script in process“ gesetzt werden darf. Multithreading wiederum ist in-process-fähig, wird aber durch das Geo- processing-Framework direkt nicht unterstützt. Multithreading mit Geo- processing funktioniert deshalb nur in Verbindung mit dem Modul sub- process, bei dem jeder Thread seinen Job in einen eigenen Prozess auslagert und so lange wartet, bis dieser – wiederum out-of-process – seine Aufgabe erledigt hat. Das setzt bei der Implementierung aller- dings voraus, dass der Code für die einzelnen Jobs in ein eigenes Py- thon-Skript ausgelagert werden muss. Wie viele Jobs und Prozesse sind eigentlich ideal? Die Anzahl der Pro- zesse, die gleichzeitig Jobs bearbeiten, ist optimal, wenn alle System- ressourcen über den gesamten Verarbeitungszeitraum ausgeschöpft werden können. Wenn es möglich ist, die zu verarbeitenden Daten so gleichmäßig aufzuteilen, dass jeder Job in etwa gleich lange arbeitet, ist pro Job ein Prozess und ein Prozess pro CPU ideal. Anzahl der CPUs in Python: noOfJobs = multiprocessing.cpu_count() Viele kleine Jobs würden in diesem Fall einen zusätzlichen und unnöti- gen Overhead bewirken. Können die Daten allerdings nur zufällig und heterogen auf die Jobs verteilt werden (zum Beispiel durch die Verwen- dung eines regelmäßigen räumlichen Gitters), sind vielleicht drei oder vier Jobs pro CPU günstiger, ansonsten läuft man Gefahr, dass einer dieser Prozesse sehr schnell beendet ist, ein anderer aber sehr lange dauern kann – und in der Zwischenzeit die Ressourcen des ersten nicht weiter genutzt werden. Haben Sie also eine zu verarbeitende Objektliste auf der einen Seite und vier CPUs für die Verarbeitung auf der anderen Seite, könnte es eine gute Strategie sein, die Objektliste (zum Beispiel OIDs 1 bis 100000) in vier gleich große Objektlisten (OIDs 1 bis 25000, 25001 bis 50000, 50001 bis 75000, 75001 bis 100000) aufzuteilen und vier Jobs – einer pro Liste – zu definieren, die gleichzeitig mit vier Prozessen abge- arbeitet werden. Haben Sie vier CPUs und Daten, die über ein großes Gebiet verteilt sind, hat es unter Umständen Sinn, sie räumlich mithilfe eines Gitters aufzuteilen. Jedes Gitter wird duch einen Job verarbeitet. Da die Men- ge der Daten pro Job aber in der Regel unterschiedlich groß ist, könn- te es hier eine gute Strategie sein, mehr als nur vier Jobs zu definieren: Ein Gitter mit 16 Flächen definiert 16 Jobs, die durch vier gleichzeitige Prozesse abgearbeitet werden. Während ein Prozess dann einen Job mit sehr vielen Daten verarbeitet, kann ein anderer Prozess in dieser Zeit mehrere Jobs mit weniger Daten verarbeiten. Entsprechend einer dieser Verteilstrategien (gleichmäßig oder zufällig) wählt man in Python die dazu passende Implementierung. Können die Daten gleichmäßig auf so viele Jobs wie verfügbare CPUs verteilt wer- den, ist die Thread- oder die Multiprocessing.Process-Strategie am geeignetsten, bei denen jeder Job gezielt einem Prozess zugeordnet wird. Definiert man viele kleine Jobs, ist die Multiprocessing.Pool-Imple- mentierung die effektivste, weil hier die Jobs dynamisch den Prozessen zugewiesen werden: Hat ein Prozess einen Job abgearbeitet, wird ihm automatisch ein neuer Job zugewiesen. Beschleunigte Geoverarbeitung durch Multiprocessing/Multithreading in ArcGIS for Desktop TIPPS UND TRICKS FÜR ANWENDER

Seitenübersicht