【发布时间】:2020-02-05 08:20:53
【问题描述】:
Google Cloud 提供了一个具有 96 个内核的虚拟机实例。
我认为拥有这 96 个内核,您可以将程序分成 95 个切片,同时让另一个内核运行程序,这样您可以将程序运行速度提高 95 倍。
然而,事情并非如此。
我正在用 Python 运行一个简单的程序,它的数量只有 2000 万。
在我的 Mac 书上,串行运行这个程序需要 4.6 秒,而当我把这个过程分成 4 个部分并并行运行时,需要 1.2 秒。
我的 Mac 书具有以下规格:
版本 10.14.5
处理器 2.2 GHz 英特尔酷睿 i7
2015 年中
内存 16GB 1600 MHz DDR3
gcloud 提供的计算机基本上只是慢了一点。
当我串行运行程序时,它需要相同的时间。当我将程序分成 95 个部分时,它实际上需要更多时间:2.6 秒。当我把程序分成4份时,需要1.4秒才能完成。该计算机具有以下规格:
n1-highmem-96(96 个 vCPU,624 GB 内存)
我需要高内存,因为我要索引一个 140 亿字的语料库。我将保存 100,000 个最常用词的位置。
当我保存这些位置时,我将腌制它们。
腌制文件会占用大量时间,并且可能会消耗 90% 的时间。
正是由于这个原因,我需要尽可能少地腌制文件。因此,如果我可以尽可能长时间地将位置放入 python 对象中,那么我将为自己节省很多时间。
这是我正在使用的 Python 程序,以防万一:
import os, time
p = print
en = enumerate
def count_2_million(**kwargs):
p('hey')
start = kwargs.get("start")
stop = kwargs.get("stop")
fork_num = kwargs.get('fork_num')
for x in range(start, stop):
pass
b = time.time()
c = round(b - kwargs['time'], 3)
p(f'done fork {fork_num} in {c} seconds')
def divide_range(divisions: int, total: int, idx: int, begin=0):
sec = total // divisions
start = (idx * sec) + begin
if total % divisions != 0 and idx == divisions:
stop = total
else:
stop = start + sec
return start, stop
def main_fork(func, total, **kwargs):
forks = 4
p(f'{forks} forks')
kwargs['time'] = time.time()
pids = []
for i in range(forks):
start1, stop1 = 0, 0
if total != -1:
start1, stop1 = divide_range(4, total, i)
newpid = os.fork()
pids.append(newpid)
kwargs['start'] = start1
kwargs['stop'] = stop1
kwargs['fork_num'] = i
if newpid == 0:
p(f'fork num {i} {start1} {stop1}')
child(func, **kwargs)
return pids
def child(func, **kwargs):
func(**kwargs)
os._exit(0)
main_fork(count_2_million, 200_000_000, **{})
【问题讨论】: