gpt4 book ai didi

python - 在 numpy.zeros 中第一次接触内存后如何处理?

转载 作者:行者123 更新时间:2023-12-05 04:41:29 34 4
gpt4 key购买 nike

我最近看到,当通过 np.emptynp.zeros 创建一个 numpy 数组时,该 numpy 数组的内存实际上并没有被操作系统分配,因为在 this answer 中讨论(和 this question ),因为 numpy 利用 calloc 来分配数组的内存。

In fact, the OS isn't even "really" allocating that memory until you try to access it.

因此,

l = np.zeros(2**28)

不会增加系统报告的已用内存,例如,在 htop 中。只有当我触及内存时,例如通过执行

np.add(l, 0, out=l)

使用的内存增加了。

由于这种行为,我有几个问题:

1。触摸内存是否在幕后被复制?

如果我只是在一段时间后才接触内存块,操作系统是否会在后台复制 numpy 数组的内容以保证内存是连续的?

i = 100
f[:i] = 3

while True:
... # Do stuff
f[i] = ... # Once the memory "behind" the already allocated chunk of memory is filled
# with other stuff, does the operating system reallocate the memory and
# copy the already filled part of the array to the new location?
i = i + 1

2。触摸最后一个元素

由于numpy数组的内存在内存中是连续的,我认为

f[-1] = 3

可能需要分配整个内存块(不触及整个内存)。然而,事实并非如此,htop 中使用的内存不会随着数组的大小而增加。为什么不是这样?

最佳答案

OS isn't even "really" allocating that memory until you try to access it

这取决于目标平台(通常是操作系统及其配置)。一些平台直接在物理内存中分配页面(例如 AFAIK XBox 和一些嵌入式平台一样)。然而,主流平台确实这样做了。

1. Is touched memory copied under the hood?
If I touch chunks of the memory only after a while, is the content of the numpy array copied under the hood by the operating system to guarantee that the memory is contiguous?

分配在虚拟内存 中执行。在给定的内存页面(固定大小的 block ,例如 4 KiB)上完成第一次触摸时,操作系统将虚拟页面映射到物理页面。因此,当您只设置数组的一项时,只有一页将被物理映射(除非该项目跨越两页,这只发生在病态情况下)。

对于一组连续的虚拟页面,物理页面可能不是连续的。但是,这不是问题,您不应该关心它。这主要是操作系统的工作。话虽这么说,现代处理器有一个名为 TLB 的专用单元,用于将虚拟地址(您可以通过调试器看到的地址)转换为物理地址(因为这种转换相对昂贵和性能至关重要)。

virtual memory example

由于分页,Numpy 数组的内容不会重新分配或复制(至少从用户的角度来看,即在虚拟内存中)。

2. Touching the last element
I thought f[-1] = 3 might require the entire block of memory to be allocated (without touching the entire memory). However, it does not, the utilized memory in htop does not increase by the size of the array. Why is that not the case?

由于分页,只有与 Numpy 数组关联的虚拟内存中的最后一页被映射。这就是为什么您看不到 htop 有很大变化的原因。但是,如果仔细观察,您应该会看到细微的变化(您平台上的页面大小)。否则,这应该意味着由于其他先前的回收分配,页面已经被映射。实际上,分配库可以预分配内存区域以加快分配速度(通过减少对操作系统的慢速请求的数量)。该库还可以在 Numpy 释放内存时保持内存映射,以加速下一次分配(因为内存不必取消映射然后再次映射)。这在实践中不太可能发生在巨大的阵列上,因为对内存消耗的影响太昂贵了。

关于python - 在 numpy.zeros 中第一次接触内存后如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70055063/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com