[英]Is shared readonly data copied to different processes for multiprocessing?
[英]Multiprocessing: why is a numpy array shared with the child processes, while a list is copied?
我使用這個腳本 (參見最后的代碼)來評估在父進程分叉時是共享還是復制全局對象。
簡而言之,該腳本創建一個全局data
對象,子進程迭代data
。 該腳本還監視內存使用情況,以評估對象是否已在子進程中復制。
結果如下:
data = np.ones((N,N))
。 子進程中的操作: data.sum()
。 結果: 共享 data
(無副本) data = list(range(pow(10, 8)))
。 子進程中的操作: sum(data)
。 結果: 復制 data
。 data = list(range(pow(10, 8)))
。 子進程中的操作: for x in data: pass
。 結果: 復制 data
。 由於寫時復制,預期結果1)。 我對結果2)和3)感到有些困惑。 為什么要復制data
?
腳本
import multiprocessing as mp
import numpy as np
import logging
import os
logger = mp.log_to_stderr(logging.WARNING)
def free_memory():
total = 0
with open('/proc/meminfo', 'r') as f:
for line in f:
line = line.strip()
if any(line.startswith(field) for field in ('MemFree', 'Buffers', 'Cached')):
field, amount, unit = line.split()
amount = int(amount)
if unit != 'kB':
raise ValueError(
'Unknown unit {u!r} in /proc/meminfo'.format(u = unit))
total += amount
return total
def worker(i):
x = data.sum() # Exercise access to data
logger.warn('Free memory: {m}'.format(m = free_memory()))
def main():
procs = [mp.Process(target = worker, args = (i, )) for i in range(4)]
for proc in procs:
proc.start()
for proc in procs:
proc.join()
logger.warn('Initial free: {m}'.format(m = free_memory()))
N = 15000
data = np.ones((N,N))
logger.warn('After allocating data: {m}'.format(m = free_memory()))
if __name__ == '__main__':
main()
詳細結果
運行1輸出
[WARNING/MainProcess] Initial free: 25.1 GB [WARNING/MainProcess] After allocating data: 23.3 GB [WARNING/Process-2] Free memory: 23.3 GB [WARNING/Process-4] Free memory: 23.3 GB [WARNING/Process-1] Free memory: 23.3 GB [WARNING/Process-3] Free memory: 23.3 GB
運行2輸出
[WARNING/MainProcess] Initial free: 25.1 GB [WARNING/MainProcess] After allocating data: 21.9 GB [WARNING/Process-2] Free memory: 12.6 GB [WARNING/Process-4] Free memory: 12.7 GB [WARNING/Process-1] Free memory: 16.3 GB [WARNING/Process-3] Free memory: 17.1 GB
運行3輸出
[WARNING/MainProcess] Initial free: 25.1 GB [WARNING/MainProcess] After allocating data: 21.9 GB [WARNING/Process-2] Free memory: 12.6 GB [WARNING/Process-4] Free memory: 13.1 GB [WARNING/Process-1] Free memory: 14.6 GB [WARNING/Process-3] Free memory: 19.3 GB
他們都是寫字復制品。 你缺少的是,當你這樣做時,例如,
for x in data:
pass
data
包含的每個對象的引用計數暫時遞增1,每次一個,因為x
依次綁定到每個對象。 對於int
對象,CPython中的refcount是基本對象布局的一部分,因此對象被復制(你確實改變了它,因為refcount改變了)。
為了使某些更類似於numpy.ones
情況,請嘗試,例如,
data = [1] * 10**8
然后列表中只有一個唯一的對象引用了很多( 10**8
)次,因此復制很少(同一對象的引用計數會多次遞增和遞減)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.