【问题标题】:Python code with multiprocessing is slower with 32 cores than 16 cores on AWS EC2具有多处理功能的 Python 代码在 AWS EC2 上使用 32 核比 16 核慢
【发布时间】:2018-08-27 14:45:16
【问题描述】:

我不明白为什么我在 AWS EC2 c3.8xlarge 上使用 28-30 个内核时的计算时间比使用 12-16 个内核时要长。我做了一些测试,结果如下图:

https://www.dropbox.com/s/8u32jttxmkvnacd/Slika%20zaslona%202015-01-11%20u%2018.33.20.png?dl=0

最快的计算是当我使用 13 个内核时。因此,如果我使用最大内核数,则与我使用 8 个 c3.8xlarge 内核的时间相同:

https://www.dropbox.com/s/gf3bevbi8dwk5vh/Slika%20zaslona%202015-01-11%20u%2018.32.53.png?dl=0

这是我使用的简化代码。

import random
import multiprocessing as mp
import threading as th
import numpy as np

x=mp.Value('f',0)
y=mp.Value('f',0)
arr=[]
tasks=[]
nesto=[]

def calculation2(some_array):
    global x, y, arr
    p=False
    a = np.sum(some_array)*random.random()
    b = a **(random.random())
    if a > x.value:
        x.value=a
        y.value=b
        arr=some_array
        p=True
    if p:
        return x.value, y.value, arr

def calculation1(number_of_pool):
    global tasks
    pool=mp.Pool(number_of_pool)
    for i in range(1,500):
        some_array=np.random.randint(100, size=(1, 4))
        tasks+=[pool.apply_async(calculation2,args=(some_array,))]

def exec_activator():
    global x, y, arr
    while tasks_gen.is_alive() or len(tasks)>0:
        try:
            task=tasks.pop(0)
            x.value, y.value, arr = task.get()
        except:
            pass

def results(task_act):
    while task_act.is_alive():
        pass
    else:
        print x.value
        print y.value
        print arr

tasks_gen=th.Thread(target=calculation1,args=(4,))
task_act=th.Thread(target=exec_activator)
result_print=th.Thread(target=results,args=(task_act,))

tasks_gen.start()
task_act.start()
result_print.start()

它的核心是两个计算:

  • 计算 1 - 计算数组并​​为计算 2 制作作业 用那个数组
  • 计算 2 - 计算数组外的一些计算并比较结果

代码的目标是找到计算最大 x 的数组,并返回它的 y。 这两个计算同时开始(使用线程),因为有时有太多的数组占用了太多的 RAM。

我的目标是进行最快的计算。如果可能,我需要建议如何使用所有内核。

如果英语不好,请提前道歉。如果您需要更多信息,请询问。

【问题讨论】:

  • 与可用的 RAM 相比,内核过多,您可能正在使用虚拟内存(为了简化起见,与磁盘交换/交换),这很容易减慢您的速度。唯一通用的解决方案是获得更多的 RAM。根据您任务的细节,实际上以正确的顺序方式从磁盘工作可能比将其全部吸入可以是虚拟的“内存”中更快。或者,如果您可以使用本地 SSD 作为您的“磁盘”,则可以提供更快的随机访问(我不知道如何在 AWS 中做到这一点,仅在 Google Cloud Platform 上)。
  • 我正在使用 psutil 来监督处理器和 RAM。在测试数据上,它最多使用 2-3% 的 RAM。我在 Ubuntu 服务器 (EBS) 上传输所有数据和 python 代码。
  • 有趣的话题。你如何测试它,我在一个微型实例上运行它,并在 0.2s 内得到更少的结果[[86 44 89 88]] \n real 0m0.175s
  • 上面的代码是简化的代码,它在任何计算机上都非常快,我放它只是为了展示我是如何构建真实代码的。这里我只是放了一些随机数组来计算一些随机数据。真正的代码要长 3-4 倍,而且更复杂,它取决于我硬盘上的盘中股票数据。 def 和变量是用我的母语写的,所以我必须做很多改动才能在这里展示出来。
  • 根据aws.amazon.com/ec2/instance-types,您有 32 个超线程,而不是物理内核。

标签: python amazon-ec2 multiprocessing


【解决方案1】:

c3.8xlarge 是 Ivy Bridge 四核系统。它使用超线程;它实际上并没有 32 个(硬件)独立的处理单元。

尝试在比硬件中的处理器更多的操作系统进程中并行处理受 CPU 限制的任务通常是没有意义的。实际上,由于资源开销和上下文切换(这就是您所看到的),这通常是有害的。

这可能取决于您的特定应用程序,而实验将帮助您找到最佳位置(听起来您已经做到了)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    相关资源
    最近更新 更多