Maximale CPU-Auslastung

9

Mein Skript schneidet Linien mit Polygonen. Es ist ein langer Prozess, da es mehr als 3000 Linien und mehr als 500000 Polygone gibt. Ich habe von PyScripter ausgeführt:

# Import
import arcpy
import time

# Set envvironment
arcpy.env.workspace = r"E:\DensityMaps\DensityMapsTest1.gdb"
arcpy.env.overwriteOutput = True

# Set timer
from datetime import datetime
startTime = datetime.now()

# Set local variables
inFeatures = [r"E:\DensityMaps\DensityMapsTest.gdb\Grid1km_Clip", "JanuaryLines2"]
outFeatures = "JanuaryLinesIntersect"
outType = "LINE"

# Make lines
arcpy.Intersect_analysis(inFeatures, outFeatures, "", "", outType)

#Print end time
print "Finished "+str(datetime.now() - startTime)


Meine Frage ist: Gibt es eine Möglichkeit, die CPU zu 100% funktionsfähig zu machen? Es läuft die ganze Zeit mit 25%. Ich denke, dass das Skript schneller laufen würde, wenn der Prozessor auf 100% wäre. Falsch geraten?
Meine Maschine ist:

  • Windows Server 2012 R2 Standard
  • Prozessor: Intel Xeon CPU E5-2630 0 bei 2,30 GHz 2,29 GHz
  • Installierter Speicher: 31,6 GB
  • Systemtyp: 64-Bit-Betriebssystem, x64-basierter Prozessor


Geben Sie hier die Bildbeschreibung ein

Manuel Frias
quelle
Ich würde dringend empfehlen, sich für Multithreading zu entscheiden. Das ist nicht trivial einzurichten, wird aber die Anstrengungen mehr als kompensieren.
Alok Jha
1
Welche Art von räumlichem Index haben Sie auf Ihre Polygone angewendet?
Kirk Kuykendall
1
Haben Sie den gleichen Vorgang auch mit ArcGIS Pro versucht? Es ist 64 Bit und unterstützt Multithreaded. Ich wäre überrascht, wenn es klug genug wäre, einen Schnittpunkt in mehrere Threads aufzuteilen, aber einen Versuch wert.
Kirk Kuykendall
Die Polygon-Feature-Class hat einen räumlichen Index mit dem Namen FDO_Shape. Ich habe nicht darüber nachgedacht. Soll ich noch einen erstellen? Ist das nicht genug?
Manuel Frias
1
Da Sie viel RAM haben ... haben Sie versucht, die Polygone in eine speicherinterne Feature-Class zu kopieren und dann die Linien damit zu schneiden? Oder haben Sie versucht, es auf der Festplatte zu komprimieren? Angeblich verbessert das Verdichten die E / A.
Kirk Kuykendall

Antworten:

13

Lassen Sie mich raten: Ihre CPU hat 4 Kerne, also 25% CPU-Auslastung, 100% Auslastung eines Kerns und 3 inaktive Kerne.

Die einzige Lösung besteht darin, den Code multithreaded zu machen, aber das ist keine einfache Aufgabe.

MTilsted
quelle
4
Die von ihm erwähnte CPU verwendet 6 Kerne und 12 Threads.
Kersten
5
Hallo, ich kann nicht abstimmen, aber ich würde gerne! Python hat leider eine GIL, so dass Sie überhaupt kein Multithread-Zeug können (das Beste, was Sie tun können, ist, die GIL freizuschalten, wenn ein Thread auf einem Systemaufruf blockiert)
Alec Teal
2
@AlecTeal können Sie definitiv, zum Beispiel mit Jython oder dem multiprocessingModul.
Rechtsfalte
@elyse geht "Oh ja, das kannst du in Python total machen, wenn du mit Python Jython meinst" zählt nicht. Ich müsste mich mit Multiprocessing befassen. Würde ein Import die Möglichkeit haben, neu zu implementieren, was Python Python ausmacht?
Alec Teal
@AlecTeal Es werden Prozesse erzeugt (eine Möglichkeit, Parallelität herzustellen). Siehe die Dokumentation des multiprocessingModuls.
Rechtsfalte
13

Ich bin mir nicht sicher, ob dies eine CPU-gebundene Aufgabe ist. Ich würde denken, dass es sich um eine E / A-gebundene Operation handelt, also würde ich versuchen, die schnellste Festplatte zu verwenden, auf die ich Zugriff hatte.

Wenn E: ein Netzwerklaufwerk ist, wäre das Entfernen der erste Schritt. Wenn es sich nicht um eine Hochleistungsfestplatte handelt (<7 ms Suche), ist dies die zweite. Sie können einen gewissen Vorteil erzielen, wenn Sie die Polygonebene in einen in_memoryArbeitsbereich kopieren. Der Vorteil hängt jedoch möglicherweise von der Größe der Polygon-Feature-Class und davon ab, ob Sie die 64-Bit-Hintergrundverarbeitung verwenden.

Die Optimierung des E / A-Durchsatzes ist häufig der Schlüssel zur GIS-Leistung. Ich empfehle daher, weniger auf die CPU-Anzeige und mehr auf die Netzwerk- und Festplattenanzeige zu achten.

Vince
quelle
4

Ich hatte ähnliche Leistungsprobleme in Bezug auf Arcpy-Skripte. Der größte Engpass ist nicht die CPU, sondern die Festplatte. Wenn Sie Daten aus dem Netzwerk verwenden, das das schlimmste Szenario darstellt, versuchen Sie, Ihre Daten auf das SSD-Laufwerk zu verschieben, und starten Sie das Skript über die Befehlszeile Nicht von Pyscripter, Pyscripter ist etwas langsamer. Dies kann daran liegen, dass es einige Debugging-Elemente enthält. Wenn Sie nicht erneut zufrieden sind, sollten Sie über eine Parallelisierung Ihres Skripts nachdenken, da jeder Python-Thread einen CPU-Kern benötigt und Ihre CPU 6 Kerne hat, sodass Sie starten können 6 Skripte gleichzeitig.

Geogeek
quelle
3

Wenn Sie Python verwenden und wie oben vorgeschlagen, sollten Sie Multiprocessing verwenden, wenn Ihr Problem parallel ausgeführt werden kann.

Ich habe auf der Geonet-Website einen kleinen Artikel über die Konvertierung eines Python-Skripts in ein Python-Skript-Tool geschrieben, das in Modelbuilder verwendet werden kann. Das Dokument listet den Code auf und beschreibt einige Fallstricke für die Ausführung als Skript-Tool. Dies ist nur ein Ort, um zu suchen:

https://geonet.esri.com/docs/DOC-3824

Hornbydd
quelle
Dies scheint der richtige Weg zu sein! Ihr Skript funktioniert einwandfrei, aber ich weiß nicht, wie ich es ändern soll, damit es mit meinem Skript funktioniert. Besser, ich dachte daran, eine tabellarische Schnittmenge mit Polygonen und Linien zu erstellen. Irgendeine Idee?
Manuel Frias
3

Wie bereits erwähnt, sollten Sie Multiprocessing oder Threading verwenden . Aber hier kommt die Einschränkung: Das Problem muss teilbar sein! Schauen Sie sich also https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms an .

Wenn Ihr Problem teilbar ist, würden Sie wie folgt vorgehen:

  • Erstellen Sie eine Warteschlange, in der Sie die Eingabedaten für die Prozesse / den Thread speichern
  • Erstellen Sie eine Warteschlange, in der die Ergebnisse gespeichert werden
  • Erstellen Sie eine Funktion oder Klasse, die als Prozess / Thread verwendet werden kann, um unser Problem zu lösen

Aber wie Geogeek gesagt hat, handelt es sich möglicherweise nicht um ein CPU-Begrenzungsproblem, sondern um ein E / A-Problem. Wenn Sie über genügend RAM verfügen, können Sie alle Daten vorladen und dann verarbeiten. Dies hat den Vorteil, dass die Daten auf einmal gelesen werden können, wodurch der Berechnungsprozess nicht immer unterbrochen wird.

Benjamin
quelle
3

Ich beschloss, es mit 21513 Linien und 498596 Polygonen zu testen. Ich habe den Multiprozessor-Ansatz (12 Prozessoren auf meinem Computer) mit diesem Skript getestet:

import arcpy,os
import multiprocessing
import time
t0 = time.time()
arcpy.env.overwriteOutput = True
nProcessors=4
folder=r'd:\scratch'

def function(inputs):
        nGroup=inputs[0]
        pGons=inputs[1]
        lines=inputs[2]
        outFeatures = '%s%s%s_%i.shp' %(folder,os.sep,'inters',nGroup)
        fids= tuple([i for i in range(nGroup,500000,nProcessors-1)])
        lyr='layer%s'%nGroup
        query='"FID" in %s' %str(fids)
        arcpy.MakeFeatureLayer_management(pGons,lyr,query)
        arcpy.Intersect_analysis([lines,lyr], outFeatures)
        return outFeatures
if __name__ == "__main__":
        inPgons='%s%s%s' %(folder,os.sep,'parcels.shp')
        inLines='%s%s%s' %(folder,os.sep,'roads.shp')
        m,bList=0,[]
        for i in range(nProcessors):
                bList.append([i,inPgons,inLines])
        pool = multiprocessing.Pool(nProcessors-1)
        listik=pool.map(function, bList)
##      apply merge here
        print listik
        print ('%i seconds' %(time.time()-t0))

Ergebnisse, Sekunden:

  • normale lokale Festplatte - 191
  • superschnelle lokale Fahrt - 220
  • Netzwerklaufwerk - 252

Das Komische, dass es mit dem Geoverarbeitungswerkzeug von mxd nur 87 Sekunden gedauert hat. Vielleicht stimmt etwas mit meiner Herangehensweise an den Pool nicht ...

Wie man sehen kann, habe ich in (0, 4, 8,12… 500000) eine ziemlich hässliche Abfrage-FID verwendet, um die Aufgabe teilbar zu machen.

Es ist möglich, dass eine Abfrage basierend auf einem vorberechneten Feld, z. B. CFIELD = 0, die Zeit erheblich verkürzt.

Ich habe auch festgestellt, dass die von Multiprocessing-Tools gemeldete Zeit sehr unterschiedlich sein kann.

FelixIP
quelle
1
Ja, Sie verwenden eine Liste, die mit Sperrproblemen einhergeht. Versuchen Sie es mit einer Multiprocessing.queue. Versuchen Sie auch, keine Daten in den Arbeitsprozessen zu schreiben, sondern erstellen Sie eine Ausgabewarteschlange mit den Daten, die Sie schreiben möchten, und lassen Sie dies von einem Schreibprozess ausführen.
Benjamin
3

Ich bin mit PyScripter nicht vertraut, aber wenn es von CPython unterstützt wird, sollten Sie sich für Multiprocessing und nicht für Multithreading entscheiden, solange das Problem selbst teilbar ist (wie andere bereits erwähnt haben).

CPython verfügt über eine globale Interpreter-Sperre , die alle Vorteile aufhebt, die mehrere Threads in Ihrem Fall mit sich bringen könnten .

Sicherlich sind in anderen Kontexten Python-Threads nützlich, aber nicht in Fällen, in denen Sie an die CPU gebunden sind.

user1514631
quelle
1

Meine Frage ist: Gibt es eine Möglichkeit, die CPU zu 100% funktionsfähig zu machen?

Da Ihre CPU über mehrere Kerne verfügt, können Sie nur den Kern maximieren, auf dem Ihr Prozess ausgeführt wird. Abhängig davon, wie Sie Ihren Xeon-Chip konfiguriert haben, werden bis zu 12 Kerne ausgeführt (6 physische und 6 virtuelle mit aktiviertem Hyperthreading). Selbst 64-Bit-ArcGIS kann dies nicht wirklich nutzen - und dies kann zu CPU-Einschränkungen führen, wenn Ihr Single-Threaded-Prozess den Kern, auf dem er ausgeführt wird, maximal ausnutzt. Sie benötigen eine Multithread-Anwendung, um die Last auf die Kerne zu verteilen, oder (viel einfacher) Sie können die Anzahl der Kerne reduzieren, die Ihre CPU ausführt, um den Durchsatz zu erhöhen.

Der einfachste Weg, um die CPU-Beschränkung zu stoppen (und sicherzustellen, dass es sich tatsächlich um eine CPU-Beschränkung handelt, nicht um Festplatten-E / A-Beschränkungen), besteht darin, die BIOS-Einstellungen für Ihr Xeon zu ändern und auf einen massiven Einzelkern festzulegen. Die Leistungssteigerung wird erheblich sein. Denken Sie daran, dass dies auch die Multitasking-Fähigkeit Ihres PCs erheblich beeinträchtigt. Daher ist es am besten, wenn Sie über eine dedizierte Prozessmaschine verfügen, auf der dies implementiert werden kann. Es ist viel einfacher als der Versuch, Ihren Code mit mehreren Threads zu versehen - was die meisten ArcGIS Desktop-Funktionen (wie in 10.3.1) sowieso nicht unterstützen.

kingmi
quelle
Nach welcher Einstellung sollten Sie suchen, um Ihre CPU in "einen massiven Einzelkern" zu verwandeln?
Alex McVittie
1
Das genaue Menü hängt von Ihrem BIOS und der Chip-Firmware ab, befindet sich jedoch normalerweise im BIOS-Menü Setup> Erweitert> CPU-Konfiguration. Sie sollten das Hyper-Threading deaktivieren und dann die Anzahl der zu aktivierenden Kerne festlegen. 0 ist normalerweise alles - auf 1 setzen, wenn Sie einen großen Kern wollen. Gute Idee, sich die Einstellungen zu notieren, bevor Sie Dinge ändern - klingt offensichtlich, ist aber leicht zu übersehen, falls die Dinge nicht klappen.
Kingmi