我想使用多进程并行运行相同的代码。
我的过程代码仅在8分钟内运行。在10分钟内使用“强制单线程”的东西。但是,当我并行运行24个实例时,每个实例大约需要1个小时。
之前,当每个进程像疯子一样疯狂地跨线程时,我有1.6M的上下文切换。 然后,我使用了以下环境。强制Numpy每个进程仅使用一个线程的变量:
os.environ["NUMEXPR_NUM_THREADS"] = '1'
os.environ["OMP_NUM_THREADS"] = '1'
os.environ["MKL_THREADING_LAYER"] = "sequential" # Better than setting MKL_NUM_THREADS=1 (source: https://software.intel.com/en-us/node/528380)
即使在那之后,我的问题仍然存在。我每个进程大约需要1个小时的运行时间。 使用一览表,除了CPU使用率在95-100%(一览表为红色)之外,其余部分都是绿色,内存,带宽,甚至上下文切换都在5K左右恢复正常。
您是否知道为什么会这样?我不明白为什么当没有明显的指示器一眼就弹出时并行速度要慢6倍
答案 0 :(得分:0)
对于我的特定问题,我找到了答案。看来这是由于我的硬件而不是代码。
该代码可以在其他16个CPU的服务器上正常运行。当使用其中的15个时,我得到了8分钟的时间,这正是我想要的。
我认为旧服务器中的某些东西使多进程处理变慢。
旧服务器不起作用:
processor : 23
vendor_id : AuthenticAMD
cpu family : 16
model : 8
model name : Six-Core AMD Opteron(tm) Processor 8439 SE
stepping : 0
cpu MHz : 2800.000
cache size : 512 KB
physical id : 3
siblings : 6
core id : 5
cpu cores : 6
apicid : 29
initial apicid : 29
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate vmmcall npt lbrv svm_lock nrip_save pausefilter
bugs : tlb_mmatch fxsave_leak sysret_ss_attrs null_seg amd_e400 spectre_v1 spectre_v2
bogomips : 5600.33
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate
新服务器在其上运行:
processor : 15
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel Xeon E312xx (Sandy Bridge)
stepping : 1
microcode : 0x1
cpu MHz : 2599.998
cache size : 16384 KB
physical id : 1
siblings : 8
core id : 7
cpu cores : 8
apicid : 15
initial apicid : 15
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx hypervisor lahf_lm arat xsaveopt
bogomips : 5199.99
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:
答案 1 :(得分:0)
没有“最小代码示例”,确实很难回答,因此,我将提供一些代码,而不是直接回答。我已经尝试过:
import os
os.environ['OMP_NUM_THREADS'] = '1'
import numpy as np
import time
def tns(): return time.time_ns() / 1e9
def nps(vec, its=100):
return min(np.linalg.norm(vec - np.random.randn(len(vec))) for _ in range(its))
start = tns()
s = nps(np.random.randn(100_000))
end = tns()
print("{} took {}".format(s, end - start))
在我的机器上,设置OMP_NUM_THREADS=1
可以使速度提高约2.5倍。我从freenode上的#numpy收到的解释是我的代码受内存限制,因此多线程将无济于事。