以下代码:
prev=[]
addresses=[]
for i in range(10000):
a = np.ones(x).astype(np.float32)
prev.append(a)
address = a.__array_interface__['data'][0]
assert(address % 64 == 0)
assert((address not in addresses))
addresses.append(address)
对于x>的值,不会引发assertionError
252表明大于253的数组(或使用float16时大于505)与较小的数组排列不同。这是什么原因?
我在运行numpy 1.12.1
答案 0 :(得分:2)
您的测试循环并未完全符合您的期望。由于一次只有一个数组存在于内存中,所以很可能 - 实际上很可能 - 新的数组将被分配在与刚刚释放的内存地址相同的内存地址上。您必须做一些事情,比如将数组附加到列表中(从而使它们全部存在于内存中)以实际测试10000个不同的分配。
但是,我很容易相信您会看到真正的效果,因为内存分配器根据所分配的块的大小使用不同的策略是完全合理的。例如,在某些时候,分配器可能会停止尝试使用它已有的内存,并开始直接从操作系统请求整个内存页面。一旦达到该阈值,您就会发现所有内容都在比64更高的2次幂边界上对齐 - 可能是4096.您似乎在1024字节(包括开销)上达到某个中间阈值,它可能有趣的是测试128/256/512/1024字节对齐。
答案 1 :(得分:1)
这是我的猜测:使用对齐内存通常需要分配更大的块,然后释放在对齐边界之前分配的前端字节。
对于大型阵列来说,这是微不足道的,但对于小型阵列,引入的碎片和开销可能会带来好处。