【发布时间】:2018-10-22 17:10:31
【问题描述】:
我正在使用双处理器 Windows 机器,并尝试使用多处理库运行多个独立的 python 进程。当然,我的目标是最大限度地利用两个 CPU,以加快计算时间。我的机器的详细信息如下:
- 操作系统:适用于工作站的 Windows 10 专业版
- 内存:524 GB
- 硬盘:三星 SSD PRO 960 (NVMe)
- CPU:Xeon Gold 6154(2 倍)
我使用 Python 3.6 执行一个主脚本,然后使用多处理库生成 72 个独立于内存的工作程序。最初,我机器的所有 72 个内核都以 100% 的速度使用。然而,大约 5-10 分钟后,我的第二个 CPU 上的所有 36 个内核的使用率都降至 0%,而第一个 CPU 上的 36 个内核仍保持在 100%。我无法弄清楚为什么会这样。
关于双处理器 Windows 机器中两个 CPU 的利用率,我是否遗漏了什么?如何确保充分利用机器的潜力?作为旁注,我很好奇如果我使用的是 Linux 操作系统,这是否会有所不同?提前感谢任何愿意为此提供帮助的人。
我的 python 主脚本的表示如下:
import pandas as pd
import netCDF4 as nc
from multiprocessing import Pool
WEATHERDATAPATH = "C:/Users/..../weatherdata/weatherfile_%s.nc4"
OUTPUTPATH = "C:/Users/....outputs/result_%s.nc4"
def calculationFunction(year):
dataset = nc.Dataset(WEATHERDATAPATH%year)
# Read the data
data1 = dataset["windspeed"][:]
data2 = dataset["pressure"][:]
data3 = dataset["temperature"][:]
timeindex = nc.num2date(dataset["time"][:], dataset["time"].units)
# Do computations with the data, primarily relying on NumPy
data1Mean = data1.mean(axis=1)
data2Mean = data2.mean(axis=1)
data3Mean = data3.mean(axis=1)
# Write result to a file
result = pd.DataFrame( {"windspeed":data1Mean,
"pressure":data2Mean,
"temperature":data3Mean,},
index=timeindex )
result.to_csv(OUTPUTPATH%year)
if __name__ == '__main__':
pool = Pool(72)
results = []
for year in range(1900,2016):
results.append( pool.apply_async(calculationFunction, (year, )))
for r in results: r.get()
【问题讨论】:
-
作为后续,我做了进一步的测试,但没有解决问题。我将主脚本限制为 36 个内核,并并行执行了两次。执行第一次迭代后,我等了 10 分钟,直到第一个 CPU 上的所有 36 个内核似乎都被消耗掉了。然后我执行了第二次迭代,再次,第二台机器上的所有 36 个内核都处于活动状态 5-10 分钟,然后第二台 CPU 停止工作。我什至尝试执行脚本的第三次迭代(意味着应该同时生成 108 个工作进程),但观察到相同的结果
-
再跟进。我要求机器上的另一个用户提交他们自己的并行任务。他们没有做我所做的相同模拟,而是使用商业软件 Gurobi 提交了优化工作,并指示它使用 36 个内核。在他们的任务开始工作(并且完全使用第一个 CPU 上下波动)后,我执行了我的主脚本(限制为 36 个内核)。再次观察到相同的结果。两个 CPU 都被完全使用了一段时间,直到第二个停止,而第一个保持 100% 使用率
-
确保您使用的是 64 位 Python,因为 32 位进程仅限于单个处理器组中的 32 个内核。 64 位 Windows 以最多 64 个内核为一组管理逻辑内核,同时考虑到局部性。您可能有两组,每个 CPU 一组,每组有 36 个内核。默认情况下,进程中的线程被分配到同一个处理器组。可以通过手动创建具有不同组亲和性的线程(
CreateRemoteThreadEx,在lpAttributeList中设置组亲和性)或手动切换线程的组亲和性(SetThreadGroupAffinity)来使用其他组。 -
感谢您的提示。我确实在使用 64 位版本的 Python。我尝试查看您对处理器组的建议,但在 python 的多处理模块中没有看到指定处理器组的选项。也许我错过了什么?另一方面,我对多处理库的理解是它在操作系统上产生独立的进程,因此与多线程不同。因此,即使有两个处理器组,正如您所建议的那样,多个进程不应该已经能够同时使用它们吗?
-
理想情况下,在池中创建 72 个进程时,Windows 应在处理器组之间平均分配进程。当然,只有当 CPU 密集型工作均匀分布在池中的所有进程上时,才会产生平衡负载。它还假设进程未分配给 Job 对象,该对象通过
JobObjectGroupInformation限制将它们限制为可用组的子集。
标签: python windows pandas python-multiprocessing multiprocessor