在我的python代码中寻找内存耗尽时,我遇到了numpy.linalg.lstsq的一些奇怪行为。 似乎每次分配新的内存使用特定大小的数组调用它。
下面的示例使用these functions来获取Linux上的内存使用情况。
import numpy as np
def testit(n):
A = np.random.randn(n, 100)
b = np.random.randn(n, 10)
deltamem = []
for i in range(10):
before = memory()
x = np.linalg.lstsq(A, b)
after = memory()
deltamem.append(after-before)
return deltamem
print(testit(100))
print(testit(1024))
print(testit(1025))
print(testit(10000))
print(testit(65630))
print(testit(65640))
print(testit(70000))
输出:
100 : [208896.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
1024 : [302313472.0, 819200.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
1025 : [819200.0, 0.0, 155648.0, 0.0, 159744.0, 0.0, 0.0, 167936.0, 0.0, 159744.0]
10000 : [8564736.0, 16125952.0, 8122368.0, 8122368.0, 8126464.0, 8122368.0, 8126464.0, 8122368.0, 8126464.0, 8122368.0]
65630 : [14950400.0, 68157440.0, 3145728.0, 3145728.0, 3145728.0, 3145728.0, 3145728.0, 3145728.0, 3149824.0, 3145728.0]
65640 : [3153920.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
70000 : [1048576.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
我想在新的大小的第一个调用中分配内存是有道理的。 在某个大小之上没有分配内存似乎也是合理的。据推测,较小的矩阵系统有一些内部缓存。
困扰我的是1025到65635之间的范围:
我可以在我的Arch Linux机器上用python 3.3.3和python 2.7.6重现这个;在这两种情况下,numpy版本都是1.8.0。
更新: 这不会发生在运行相同配置的linux / python / numpy的不同机器上。这些机器之间的主要区别在于,我的是较旧的AMD Phenom CPU,而另一台则是英特尔。
我不再相信这是一个python / numpy问题 - 但问题是什么? C lib中的CPU相关优化?