最大限度地利用CPU


9

我的脚本是将线与多边形相交。因为有3000多个线和500000多个多边形,所以这是一个漫长的过程。我从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)


我的问题是:有没有办法使CPU以100%的速度工作?它一直以25%的速度运行。我猜想,如果处理器为100%,脚本将运行得更快。猜错了吗?
我的机器是:

  • Windows Server 2012 R2标准
  • 处理器:Intel Xeon CPU E5-2630 0 @ 2.30 GHz 2.29 GHz
  • 安装的内存:31.6 GB
  • 系统类型:64位操作系统,基于x64的处理器


在此处输入图片说明


我强烈建议您使用多线程。建立起来并非易事,但可以弥补上述努力。
alok jha 2015年

1
您对多边形应用了哪种空间索引?
Kirk Kuykendall

1
另外,您是否尝试过使用ArcGIS Pro进行相同的操作?它是64位的,并支持多线程。如果它足够聪明,可以将一个Intersect分解成多个线程,但是值得一试,我会感到惊讶。
Kirk Kuykendall

面要素类具有一个名为FDO_Shape的空间索引。我还没想过 我应该再创建一个吗?这还不够吗?
曼努埃尔·弗里亚斯

1
既然您有很多RAM ...您是否尝试过将多边形复制到内存中的要素类中,然后将其与线相交?或者,如果将其保留在磁盘上,是否尝试压缩它?据说压缩可以改善I / O。
Kirk Kuykendall

Answers:


13

让我猜测:您的cpu有4个核心,因此25%的cpu使用率是100%的1个核心使用率和3个空闲的核心。

因此,唯一的解决方案是使代码多线程,但这不是简单的任务。


4
他提到CPU使用6个内核和12个线程。
Kersten 2015年

5
嗨,我不能投票,但我想!不幸的是,Python有一个GIL,所以您根本不能使用多线程的东西(您可以做的最好的事情是,在系统调用中某个线程阻塞时,将GIL解锁)
Alec Teal

2
您绝对可以使用@AlecTeal,例如使用Jython或multiprocessing模块。
2015年

@elyse说道:“哦,是的,您完全可以在Python中完成此操作,如果使用Python,则意味着Jython”不计在内。我不得不研究多处理,导入是否具有重新实现Python Python的能力?
亚历克·蒂尔

@AlecTeal它产生进程(这是并行处理的一种方法)。请参阅该multiprocessing模块的文档。
2015年

13

我不确定这是CPU限制的任务。我认为这将是一个受I / O约束的操作,因此我希望使用可以访问的最快的磁盘。

如果E:是网络驱动器,则将其消除是第一步。如果它不是高性能磁盘(寻道时间小于7毫秒),那将是第二个。通过将多边形图层复制到in_memory工作区可能会获得一些好处,但是好处可能取决于多边形要素类的大小以及是否使用64位背景处理。

优化I / O吞吐量通常是GIS性能的关键,因此,建议您不要过多关注CPU仪表,而应该更多地关注网络和磁盘仪表。


4

关于arcpy脚本,我也遇到了类似的性能问题,主要的瓶颈不是CPU,而是硬盘驱动器。如果您使用的网络数据是最坏的情况,请尝试将数据移至SSD驱动器,然后从命令行启动脚本并非来自pyscripter,pyscripter稍微慢一点可能是因为它包含一些调试材料,如果您再次不满意,请考虑并行化脚本,因为每个python线程占用一个CPU内核,因此您的CPU具有6个内核,因此可以启动同时有6个脚本。


3

当您使用python时,并且如上所述,如果您的问题可以并行运行,请考虑使用多处理。

我在geonet网站上写了一篇小文章,内容涉及将python脚本转换为可在modelbuilder中使用的python脚本工具。该文档列出了代码,并描述了将其作为脚本工具运行的一些陷阱。这只是开始寻找的地方:

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


这似乎是要走的路!您的脚本可以正常工作,但我不知道如何对其进行修改以使其与我的脚本一起使用。更好的是,我正在考虑使用多边形和直线进行制表相交。任何的想法?
曼努埃尔·弗里亚斯

3

如前所述,您应该使用多重处理线程化。但是需要注意的是:这个问题必须是可分解的!因此,请看https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms

如果您的问题是可分割的,则将执行以下操作:

  • 创建一个队列,在其中存储进程/线程的输入数据
  • 创建一个将结果存储在其中的队列
  • 创建可以用作解决我们问题的进程/线程的函数或类

但是正如geogeek所说,这可能不是CPU限制问题,而是IO问题。如果您有足够的RAM,则可以预加载所有数据然后进行处理,其优点是可以一次性读取数据,因此并不总是会中断计算过程。


3

我决定使用21513条线和498596多边形对其进行测试。我使用以下脚本测试了多处理器方法(计算机上有12个处理器):

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

结果,秒:

  • 普通本地硬盘驱动器-191
  • 超高速本地驱动器-220
  • 网络驱动器-252

有趣的是,使用mxd的地理处理工具仅用了87秒。我的泳池方式可能有问题...

可以看到,我在(0,4,8,12…500000)中使用了相当难看的查询FID来使任务可分割。

基于预先计算的字段(例如CFIELD = 0)的查询可能会大大减少时间。

我还发现,多处理工具报告的时间可能相差很大。


1
是的,您使用的是列表,其中包含锁定问题。尝试使用multiprocessing.queue。另外,请尽量不要在工作进程中写出东西,而要用要写入的数据创建输出队列,并由写入器进程完成。
本杰明

3

我对PyScripter并不熟悉,但是如果它由CPython支持,那么只要问题本身是可分割的(就如其他人已经提到的那样),就应该进行多处理而不是多线程。

CPython有一个全局解释器锁,它取消了多个线程可能给带来的所有好处。

可以肯定的是,在其他情况下,python线程是有用的,但在受CPU约束的情况下则没有作用。


1

我的问题是:有没有办法使CPU以100%的速度工作

由于您的CPU有多个内核,因此您只会最大化运行进程的内核。根据您配置Xeon芯片的方式,它将最多运行12个核心(6个物理和6个虚拟化并启用超线程)。甚至64位ArcGIS也无法真正利用这一优势-当您的单线程进程将其运行核心最大化时,这可能会导致CPU限制。您需要一个多线程应用程序来在内核之间分配负载,或者(更简单地说)可以减少CPU运行的内核数量以提高吞吐量。

停止CPU限制(并确保它实际上是CPU限制而不是磁盘I / O限制)的最简单方法是更改​​Xeon的BIOS设置并将其设置为一个大型单核。性能提升将是可观的。请记住,这也相当折衷了您的PC的多任务处理能力,因此,如果您有专用的处理机来实现这一点,则最好。这比尝试对代码进行多线程处理要简单得多-大多数ArcGIS Desktop功能(截至10.3.1版)都不支持。


您应该寻找什么设置才能将CPU变成“一个庞大的单核”?
Alex McVittie

1
确切的菜单取决于您的BIOS和芯片固件,但通常位于BIOS菜单设置>高级> CPU配置中。您将需要关闭超线程,然后设置要激活的内核数。通常为0-如果需要一个大内核,则设置为1。在更改之前请记下设置的好主意-听起来很明显,但是如果事情不起作用,则很容易忽略。
kingmi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.