Tối đa hóa việc sử dụng CPU


9

Kịch bản của tôi là giao cắt các dòng với đa giác. Đó là một quá trình lâu dài vì có hơn 3000 dòng và hơn 500000 đa giác. Tôi đã thực hiện từ 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)


Câu hỏi của tôi là: có cách nào để CPU hoạt động ở mức 100% không? Nó chạy ở mức 25% mọi lúc. Tôi đoán rằng tập lệnh sẽ chạy nhanh hơn nếu bộ xử lý ở mức 100%. Đoán sai?
Máy của tôi là:

  • Tiêu chuẩn Windows Server 2012 R2
  • Bộ xử lý: CPU Intel Xeon E5-2630 0 @ 2.30 GHz 2.29 GHz
  • Bộ nhớ đã cài đặt: 31,6 GB
  • Loại hệ thống: Hệ điều hành 64 bit, bộ xử lý dựa trên x64


nhập mô tả hình ảnh ở đây


Tôi sẽ đề nghị mạnh mẽ để đi cho đa luồng. Đó là không tầm thường để thiết lập nhưng sẽ nhiều hơn bù đắp cho những nỗ lực.
alok jha

1
Loại chỉ số không gian nào bạn đã áp dụng cho đa giác của mình?
Kirk Kuykendall

1
Ngoài ra, bạn đã thử thao tác tương tự với ArcGIS Pro chưa? Đó là 64 bit và hỗ trợ đa luồng. Tôi sẽ ngạc nhiên nếu nó đủ thông minh để chia Intersect thành nhiều luồng, nhưng đáng để thử.
Kirk Kuykendall

Lớp tính năng đa giác có một chỉ mục không gian có tên là FDO_Shape. Tôi chưa nghĩ về điều này. Tôi có nên tạo một cái khác? Điều này là không đủ?
Manuel Frias

1
Vì bạn đã có rất nhiều RAM ... bạn đã thử sao chép các đa giác vào một featureclass trong bộ nhớ và sau đó giao nhau với các dòng đó chưa? Hoặc nếu giữ nó trên đĩa, bạn đã thử nén nó chưa? Nén được cho là cải thiện i / o.
Kirk Kuykendall

Câu trả lời:


13

Hãy để tôi đoán: CPU của bạn có 4 lõi, vì vậy 25% sử dụng cpu, là 100% sử dụng một lõi và 3 lõi nhàn rỗi.

Vì vậy, giải pháp duy nhất là làm cho mã đa luồng, nhưng đó không phải là nhiệm vụ đơn giản.


4
Các CPU ông đề cập đến sử dụng 6 lõi và 12 luồng.
Kersten

5
Xin chào, tôi không thể downvote nhưng tôi muốn! Python không may có GIL nên bạn hoàn toàn không thể đọc nhiều thứ (điều tốt nhất bạn có thể làm là mở khóa GIL khi một chuỗi xử lý trên một tòa nhà chọc trời)
Alec Teal

2
@AlecTeal bạn chắc chắn có thể, ví dụ với Jython hoặc multiprocessingmô-đun.
đúng vào

@elyse sẽ "Ồ vâng, bạn hoàn toàn có thể làm điều đó trong Python, nếu bởi Python bạn có nghĩa là Jython" không được tính. Tôi phải xem xét đa xử lý, liệu một lần nhập có khả năng thực hiện lại những gì tạo ra Python Python không?
Alec Teal

@AlecTeal Nó sinh ra các quá trình (đó là một cách để thực hiện song song). Xem tài liệu của multiprocessingmô-đun.
đúng

13

Tôi không chắc chắn rằng đây là một nhiệm vụ gắn với CPU. Tôi nghĩ rằng đó sẽ là một hoạt động ràng buộc I / O, vì vậy tôi đang tìm cách sử dụng đĩa nhanh nhất mà tôi có quyền truy cập.

Nếu E: là một ổ đĩa mạng, thì việc loại bỏ đó sẽ là bước đầu tiên. Nếu đó không phải là đĩa hiệu suất cao (<7ms tìm kiếm), thì đó sẽ là thứ hai. Bạn có thể đạt được một số lợi ích từ việc sao chép lớp đa giác vào in_memorykhông gian làm việc, nhưng lợi ích có thể phụ thuộc vào kích thước của lớp tính năng đa giác và liệu bạn có đang sử dụng xử lý nền 64 bit hay không.

Tối ưu hóa thông lượng I / O thường là chìa khóa cho hiệu suất của GIS, vì vậy tôi khuyên bạn nên ít chú ý đến đồng hồ CPU và chú ý nhiều hơn đến các đồng hồ đo mạng và đĩa.


4

Tôi gặp vấn đề tương tự về hiệu năng liên quan đến các tập lệnh Arcpy, nút cổ chai lớn không phải là CPU mà là ổ cứng, nếu bạn đang sử dụng dữ liệu từ mạng đó là tình huống xấu nhất, hãy thử chuyển dữ liệu của bạn sang ổ SSD, sau đó khởi chạy tập lệnh của bạn từ dòng lệnh không phải từ pyscripter, pyscripter chậm hơn một chút có thể là do nó chứa một số thứ gỡ lỗi, nếu bạn không hài lòng một lần nữa, hãy nghĩ về việc song song tập lệnh của bạn, bởi vì mỗi luồng python lấy một lõi CPU, CPU của bạn có 6 lõi, vì vậy bạn có thể khởi chạy 6 kịch bản cùng một lúc.


3

Vì bạn đang sử dụng python và như đã đề xuất ở trên, hãy cân nhắc sử dụng đa xử lý nếu vấn đề của bạn có thể được chạy song song.

Tôi đã viết một bài viết nhỏ trên trang web geonet về việc chuyển đổi một kịch bản python thành một công cụ kịch bản python có thể được sử dụng trong modelbuilder. Tài liệu liệt kê mã và mô tả một số cạm bẫy để chạy nó như một công cụ kịch bản. Đây chỉ là một nơi để bắt đầu tìm kiếm:

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


Đây có vẻ là con đường để đi! Kịch bản của bạn hoạt động tốt nhưng tôi không biết cách sửa đổi nó để làm cho nó hoạt động với kịch bản của mình. Tốt hơn, tôi đã nghĩ đến việc thực hiện Giao lộ Tabulation với đa giác và đường thẳng. Bất kỳ ý tưởng?
Manuel Frias

3

Như đã nói trước khi bạn nên sử dụng đa xử lý hoặc luồng . Nhưng đây là lời cảnh báo: Vấn đề phải chia hết! Vì vậy, hãy xem https://en.wikipedia.org/wiki/Divide_and_conquer_alacticms .

Nếu vấn đề của bạn là chia hết, bạn sẽ tiến hành như sau:

  • Tạo một hàng đợi nơi bạn lưu trữ dữ liệu đầu vào cho các tiến trình / luồng
  • Tạo một hàng đợi trong đó các kết quả được lưu trữ trong
  • Tạo một hàm hoặc lớp có thể được sử dụng như một tiến trình / luồng giải quyết vấn đề của chúng ta

Nhưng như geogeek đã nói, nó có thể không phải là vấn đề hạn chế CPU, mà là vấn đề IO. Nếu bạn có đủ RAM, bạn có thể tải trước tất cả dữ liệu và sau đó xử lý nó, điều này có lợi thế là dữ liệu có thể được đọc trong một lần, do đó không phải lúc nào cũng làm gián đoạn quá trình tính toán.


3

Tôi quyết định thử nghiệm nó bằng cách sử dụng 21513 dòng và 498596 đa giác. Tôi đã thử nghiệm phương pháp đa bộ xử lý (12 bộ xử lý trên máy của tôi) bằng cách sử dụng tập lệnh này:

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

Kết quả, giây:

  • ổ cứng cục bộ bình thường - 191
  • ổ đĩa cục bộ cực nhanh - 220
  • ổ đĩa mạng - 252

Điều thú vị là chỉ mất 87 giây bằng công cụ xử lý địa lý từ mxd. Có lẽ có gì đó không đúng với cách tiếp cận của tôi với hồ bơi ...

Như mọi người có thể thấy tôi đã sử dụng FID truy vấn khá xấu xí trong (0, 4, 8,12 12000 500000) để làm cho nhiệm vụ chia hết.

Có thể truy vấn dựa trên trường được tính toán trước, ví dụ CFIELD = 0 sẽ giảm thời gian rất nhiều.

Tôi cũng thấy rằng thời gian được báo cáo bởi các công cụ đa xử lý có thể thay đổi rất nhiều.


1
Vâng, bạn đang sử dụng một danh sách, đi kèm với các vấn đề khóa. Hãy thử một đa xử lý.queue. Ngoài ra, cố gắng không viết ra các công cụ trong các quy trình worker, nhưng tạo một hàng đợi ouput với dữ liệu bạn muốn viết và để điều này được thực hiện bởi một quy trình nhà văn.
Benjamin

3

Tôi không quen thuộc với PyScripter, nhưng nếu được hỗ trợ bởi CPython, thì bạn nên đi xử lý đa luồng và không đa luồng miễn là bản thân vấn đề là chia hết (như những người khác đã đề cập).

CPython có Khóa phiên dịch toàn cầu , loại bỏ mọi lợi ích mà nhiều luồng có thể mang lại trong trường hợp của bạn .

Để chắc chắn trong các bối cảnh khác, các luồng python rất hữu ích, nhưng không phải trong trường hợp CPU bị ràng buộc.


1

Câu hỏi của tôi là: có cách nào để CPU hoạt động ở mức 100%

Vì CPU của bạn có nhiều lõi, bạn sẽ chỉ sử dụng tối đa lõi mà tiến trình của bạn đang chạy. Tùy thuộc vào cách bạn cấu hình chip Xeon, nó sẽ chạy tối đa 12 lõi (6 vật lý và 6 ảo với siêu phân luồng trên). Ngay cả ArcGIS 64 bit cũng không thực sự có thể tận dụng lợi thế này - và điều đó có thể dẫn đến các hạn chế của CPU khi quy trình xử lý đơn luồng của bạn phát huy tối đa lõi mà nó đang chạy. Bạn cần một ứng dụng đa luồng để phân tán tải trên các lõi HOẶC (đơn giản hơn nhiều) bạn có thể giảm số lượng lõi mà CPU của bạn đang chạy để tăng thông lượng.

Cách dễ nhất để dừng giới hạn CPU (và đảm bảo rằng đó thực sự là giới hạn CPU chứ không phải giới hạn i / o của đĩa) là thay đổi cài đặt BIOS cho Xeon của bạn và đặt nó thành một lõi lớn. Hiệu suất tăng sẽ là đáng kể. Chỉ cần nhớ điều này cũng đánh đổi khả năng đa tác vụ trên PC của bạn khá đáng kể vì vậy tốt nhất là nếu bạn có máy xử lý chuyên dụng để thực hiện việc này. Nó đơn giản hơn nhiều so với việc cố gắng đa luồng mã của bạn - điều mà hầu hết các chức năng của ArcGIS Desktop (tại 10.3.1) dù sao cũng không hỗ trợ.


Bạn nên tìm cài đặt nào để biến CPU thành "một lõi lớn"?
Alex McVittie

1
Menu chính xác sẽ phụ thuộc vào phần sụn BIOS và chip của bạn, nhưng nó thường sẽ nằm trong Cài đặt menu BIOS> Nâng cao> Cấu hình CPU. Bạn sẽ muốn tắt siêu phân luồng và sau đó đặt số lượng lõi để kích hoạt. 0 thường là tất cả - được đặt thành 1 nếu bạn muốn một lõi lớn. Ý tưởng tốt để ghi chú các cài đặt trước khi bạn thay đổi mọi thứ - nghe có vẻ rõ ràng nhưng dễ bỏ qua nếu mọi thứ không hoạt động.
kingmi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.