Memaksimalkan penggunaan CPU

9

Script saya memotong garis dengan poligon. Ini proses yang panjang karena ada lebih dari 3000 baris dan lebih dari 500000 poligon. Saya dieksekusi dari PyScripter:

# 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)


Pertanyaan saya adalah: apakah ada cara untuk membuat CPU bekerja 100%? Ini berjalan pada 25% sepanjang waktu. Saya kira skrip akan berjalan lebih cepat jika prosesornya 100%. Tebakan yang salah?
Mesin saya adalah:

  • Windows Server 2012 R2 Standard
  • Prosesor: Intel Xeon CPU E5-2630 0 @ 2,30 GHz 2,29 GHz
  • Memori yang dipasang: 31,6 GB
  • Jenis sistem: Sistem Operasi 64-bit, prosesor berbasis x64


masukkan deskripsi gambar di sini

Manuel Frias
sumber
Saya sangat menyarankan untuk menggunakan multi-threading. Itu tidak sepele untuk didirikan tetapi akan lebih dari mengimbangi upaya.
alok jha
1
Apa jenis indeks spasial yang telah Anda terapkan pada poligon Anda?
Kirk Kuykendall
1
Juga, sudahkah Anda mencoba operasi yang sama dengan ArcGIS Pro? Ini 64 bit dan mendukung multithreaded. Saya akan terkejut jika itu cukup pintar untuk memecah Intersect menjadi beberapa utas, tetapi patut dicoba.
Kirk Kuykendall
Kelas fitur poligon memiliki indeks spasial bernama FDO_Shape. Saya belum memikirkan hal ini. Haruskah saya membuat yang lain? Bukankah ini cukup?
Manuel Frias
1
Karena Anda memiliki banyak RAM ... apakah Anda mencoba menyalin poligon ke dalam fitur-kelas di memori dan kemudian memotong garis dengan itu? Atau jika menyimpannya di disk, apakah Anda mencoba memadatkannya? Seharusnya pemadatan meningkatkan i / o.
Kirk Kuykendall

Jawaban:

13

Biar saya tebak: CPU Anda memiliki 4 core, jadi 25% penggunaan CPU, adalah 100% penggunaan satu core, dan 3 core idle.

Jadi satu-satunya solusi adalah membuat kode multi-threaded, tetapi itu bukan tugas yang mudah.

MTilsted
sumber
4
The CPU ia menyebutkan menggunakan 6 core dan 12 thread.
Kersten
5
Hai, saya tidak bisa downvote tapi saya ingin! Sayangnya, Python memiliki GIL sehingga Anda tidak dapat melakukan multithread sama sekali (yang terbaik yang dapat Anda lakukan adalah membuka kunci GIL ketika sebuah thread memblokir syscall)
Alec Teal
2
@AlecTeal Anda pasti bisa, misalnya dengan Jython atau multiprocessingmodul.
rightfold
@elyse going "Oh yeah, Anda benar-benar bisa melakukannya dengan Python, jika dengan Python maksud Anda Jython" tidak masuk hitungan. Saya harus melihat ke dalam multiprocessing, apakah impor memiliki kekuatan untuk mengimplementasikan kembali apa yang membuat Python Python?
Alec Teal
@AlecTeal Ini memunculkan proses (yang merupakan salah satu cara untuk melakukan paralelisme). Lihat dokumentasi multiprocessingmodul.
sayap kanan
13

Saya tidak begitu yakin bahwa ini adalah tugas yang terikat CPU. Saya pikir itu akan menjadi operasi I / O-terikat, jadi saya akan mencari untuk menggunakan disk tercepat yang saya miliki aksesnya.

Jika E: adalah drive jaringan, maka menghilangkan itu akan menjadi langkah pertama. Jika itu bukan disk berkinerja tinggi (<7ms seek), maka itu akan menjadi yang kedua. Anda dapat memperoleh beberapa manfaat dari menyalin lapisan poligon ke in_memoryruang kerja, tetapi manfaatnya mungkin tergantung pada ukuran kelas fitur poligon, dan apakah Anda menggunakan pemrosesan latar belakang 64-bit.

Mengoptimalkan throughput I / O seringkali merupakan kunci kinerja GIS, jadi saya sarankan Anda kurang memperhatikan meter CPU dan lebih memperhatikan jaringan dan meter disk.

Vince
sumber
4

Saya memiliki masalah kinerja yang serupa mengenai skrip arcpy, hambatan utama bukanlah CPU, melainkan hard drive, jika Anda menggunakan data dari jaringan itu skenario terburuk, coba pindahkan data Anda ke drive SSD, kemudian luncurkan skrip Anda dari baris perintah bukan dari pyscripter, pyscripter sedikit lebih lambat mungkin karena mengandung beberapa hal debugging, jika Anda tidak puas lagi, pikirkan tentang paralelisasi skrip Anda, karena setiap thread python mengambil satu inti CPU, CPU Anda memiliki 6 core, sehingga Anda dapat meluncurkan 6 skrip secara bersamaan.

geogeek
sumber
3

Ketika Anda menggunakan python dan seperti yang disarankan di atas, pertimbangkan untuk menggunakan multiprocessing jika masalah Anda dapat berjalan secara paralel.

Saya menulis sebuah artikel kecil di situs web geonet tentang mengubah skrip python menjadi alat skrip python yang dapat digunakan dalam modelbuilder. Dokumen mencantumkan kode dan menjelaskan beberapa jebakan untuk menjalankannya sebagai alat skrip. Ini hanya satu tempat untuk mulai mencari:

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

Hornbydd
sumber
Ini sepertinya cara untuk pergi! Skrip Anda berfungsi dengan baik tetapi saya tidak tahu cara memodifikasinya agar berfungsi dengan skrip saya. Lebih baik, saya berpikir untuk melakukan Tabulasi Intersection dengan poligon dan garis. Ada ide?
Manuel Frias
3

Seperti yang dikatakan sebelumnya, Anda harus menggunakan multiprocessing atau threading . Tapi inilah peringatannya: Masalahnya harus dapat dibagi! Jadi lihatlah https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms .

Jika masalah Anda dapat dibagi, Anda akan melanjutkan seperti:

  • Buat antrian tempat Anda menyimpan data input untuk proses / utas
  • Buat antrian di mana hasil disimpan
  • Buat fungsi atau kelas yang dapat digunakan sebagai proses / utas yang memecahkan masalah kita

Tapi seperti yang dikatakan geogeek, itu mungkin bukan masalah pembatas CPU, tapi masalah IO. Jika Anda memiliki RAM yang cukup, Anda dapat memuat semua data dan kemudian memprosesnya, yang memiliki keuntungan bahwa data dapat dibaca dalam sekali jalan sehingga tidak selalu mengganggu proses perhitungan.

Benjamin
sumber
3

Saya memutuskan untuk mengujinya menggunakan 21513 garis dan 498596 poligon. Saya menguji pendekatan multiprosesor (12 prosesor pada mesin saya) menggunakan skrip ini:

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))

Hasil, detik:

  • hard drive lokal normal - 191
  • drive lokal supercepat - 220
  • drive jaringan - 252

Lucunya hanya butuh 87 detik menggunakan alat geoprocessing dari mxd. Mungkin ada yang salah dengan pendekatan saya ke kolam renang ...

Seperti yang dapat dilihat, saya menggunakan FID query yang jelek di (0, 4, 8,12 ... 500000) untuk membuat tugas dapat dibagi.

Ada kemungkinan bahwa kueri berdasarkan bidang yang dihitung sebelumnya, misalnya CFIELD = 0 akan sangat mengurangi waktu.

Saya juga menemukan bahwa waktu yang dilaporkan oleh alat multiprosesing bisa sangat bervariasi.

FelixIP
sumber
1
Ya Anda menggunakan daftar, yang datang bersama dengan masalah penguncian. Coba multiprocessing.queue. Juga cobalah untuk tidak menuliskan hal-hal dalam proses pekerja, tetapi membuat antrian ouput dengan data yang ingin Anda tulis dan biarkan ini dilakukan oleh proses penulis.
Benjamin
3

Saya tidak terbiasa dengan PyScripter, tetapi jika itu didukung oleh CPython, maka Anda harus pergi untuk multiprocessing dan tidak multi-threading selama masalahnya sendiri dapat dibagi (seperti yang sudah disebutkan orang lain).

CPython memiliki Global Interpreter Lock , yang membatalkan semua manfaat yang dapat dihasilkan oleh banyak utas dalam kasus Anda .

Yang pasti dalam konteks lain utas python berguna, tetapi tidak dalam kasus di mana Anda terikat CPU.

pengguna1514631
sumber
1

Pertanyaan saya adalah: apakah ada cara untuk membuat CPU bekerja 100%

Karena CPU Anda memiliki banyak inti, Anda hanya akan memaksimalkan inti proses yang sedang Anda jalankan. Bergantung pada bagaimana Anda mengonfigurasi chip Xeon Anda, chip itu akan berjalan hingga 12 core (6 fisik dan 6 virtual dengan hyperthreading aktif). Bahkan 64bit ArcGIS tidak benar-benar dapat mengambil keuntungan dari ini - dan itu dapat mengakibatkan keterbatasan CPU ketika proses ulir tunggal Anda memaksimalkan inti yang sedang berjalan. Anda memerlukan aplikasi multi-utas untuk menyebarkan beban melintasi core ATAU (lebih sederhana) Anda dapat mengurangi jumlah core yang dijalankan CPU Anda untuk meningkatkan throughput.

Cara termudah untuk menghentikan pembatasan CPU (dan pastikan itu benar-benar pembatasan CPU bukan pembatasan diska / o) adalah dengan mengubah pengaturan BIOS untuk Xeon Anda dan mengaturnya ke satu inti tunggal yang besar. Peningkatan kinerja akan sangat besar. Hanya ingat ini juga memperdagangkan kemampuan multi-tasking PC Anda dengan cukup baik, jadi yang terbaik adalah jika Anda memiliki mesin proses khusus untuk mengimplementasikannya. Ini jauh lebih sederhana daripada mencoba multi-thread kode Anda - yang sebagian besar fungsi Desktop ArcGIS (seperti pada 10.3.1) tetap tidak mendukung.

kingmi
sumber
Pengaturan apa yang harus Anda cari untuk mengubah CPU Anda menjadi "satu inti tunggal besar"?
Alex McVittie
1
Menu yang tepat akan tergantung pada BIOS dan chip firmware Anda tetapi biasanya akan berada di Setup Menu BIOS> Advanced> Konfigurasi CPU. Anda akan ingin mematikan hyper-threading dan kemudian mengatur jumlah core untuk diaktifkan. 0 biasanya diatur ke 1 jika Anda ingin satu inti besar. Ide bagus untuk mencatat pengaturan sebelum Anda mengubah sesuatu - terdengar jelas tetapi mudah diabaikan jika hal-hal tidak berhasil.
kingmi