最后说明
将我的测试留给后代,但tel 有答案。
注意
以下测试结果是在 Debian 上的。在 Ubuntu (WSL) 上进行测试确实要糟糕得多。在 Ubuntu n=193 上,任何形状崩溃(如果我将 3d n 替换为 1),以及上面的任何 n。看起来像(见下面的bla.py):
-
py bla.py n 1 在 A 上分配 3204,在 B 上为 al 0<n<193 分配 29323
- 对于
n>=193,B 上发生分段错误,3208 分配在A 上。显然,ubuntu 的某处存在一些硬内存限制。
Debian 上的旧测试
经过一些测试,它看起来像是一个内存问题,内存分配随维度的奇怪缩放。
只有 2 个维度的编辑对我来说不会崩溃,但 3 个会崩溃 - 我会假设这个来回答。
对我来说:
b = sharedctypes.RawArray(a._type_, a)
在以下情况下不会崩溃:
a = np.ctypeslib.as_ctypes(np.zeros((224**3))) #Though generating b takes a while
a = np.ctypeslib.as_ctypes(np.zeros((100,100,100)))
因此,似乎对内存的需求减少就解决了问题,但奇怪的是,一维数组中所需的相同数量的单元格工作正常 - 所以内存中更深的东西似乎正在发生。
当然,您使用的是指针。让我们尝试一些事情(bla.py):
import tracemalloc
import numpy as np
from sys import argv
from multiprocessing import sharedctypes
n,shape = (int (x) for x in argv[1:])
if shape == 1: shape = n
if shape == 2: shape = (n**2,n)
if shape == 3: shape = (n,n,n)
tracemalloc.start()
a = np.ctypeslib.as_ctypes(np.zeros(shape))
x=tracemalloc.take_snapshot().statistics('lineno')
print(len(x),sum((a.size for a in x)))
b = sharedctypes.RawArray(a._type_, a)
x=tracemalloc.take_snapshot().statistics('lineno')
print(len(x),sum((a.size for a in x)))
导致:
n shape (a mallocs sum) (b mallocs sum)
>py bla.py 100 1 => 5 3478 76 30147
>py bla.py 100 2 => 5 5916 76 948313
>py bla.py 100 3 => 5 8200 76 43033
>py bla.py 150 1 => 5 3478 76 30195
>py bla.py 150 2 => 5 5916 76 2790461
>py bla.py 150 3 => 5 8200 76 45583
>py bla.py 159 1 => 5 3478 76 30195
>py bla.py 159 2 => 5 5916 76 2937854
>py bla.py 159 3 => 5 8200 76 46042
>py bla.py 160 1 => 5 3478 76 30195
>py bla.py 160 2 => 5 5916 72 2953989
>py bla.py 160 3 => 5 8200 Segmentation fault
>py bla.py 161 1 => 5 3478 76 30195
>py bla.py 161 2 => 5 5916 75 2971746
>py bla.py 161 3 => 5 8200 75 46116
>py bla.py 221 1 => 5 3478 76 30195
>py bla.py 221 2 => 5 5916 76 5759398
>py bla.py 221 3 => 5 8200 76 55348
>py bla.py 222 1 => 5 3478 76 30195
>py bla.py 222 2 => 5 5916 76 5782877
>py bla.py 222 3 => 5 8200 76 55399
>py bla.py 223 1 => 5 3478 76 30195
>py bla.py 223 2 => 5 5916 76 5806462
>py bla.py 223 3 => 5 8200 76 55450
>py bla.py 224 1 => 5 3478 76 30195
>py bla.py 224 2 => 5 5916 72 5829381
>py bla.py 224 3 => 5 8200 Segmentation fault
>py bla.py 225 1 => 5 3478 76 30195
>py bla.py 225 2 => 5 5916 76 5853950
>py bla.py 225 3 => 5 8200 76 55552
奇怪的东西(n**2,n) 在共享类型中有大量内存分配给它,而不是n**3 或(n,n,n)。但这不是重点。
-
a mallocs 是一致的,仅略微依赖于维度,而完全不依赖于 n(对于测试的数字)。
-
b mallocs 除了在形状 2 上高,n 也略有增加,但随着形状变化很大。
- 分段错误循环出现!在我的机器上,形状
(n,n,n) 的内存分配接近一些n 依赖数字之前的sefault - 但对于n+1,我们又可以了。似乎在 160 左右约为 46k,在 224 左右约为 56k。
我没有很好的解释,但是对n 的依赖让我认为分配需要很好地适应一些位结构,有时这会中断。
我猜你的尺寸使用 225 会起作用 - 作为一种解决方法。