Ero*_*mic 2 c python memory-management numpy linux-kernel
我看着内存中的numpy数组消耗了多少空间,并且发现了一个奇怪的行为:
我跑的时候 x = np.empty((1000000, 7, 64, 64), dtype=np.uint8)
我的16GB内存的计算机没有崩溃。相反,它分配了2GB内存时运行顺利。
此numpy阵列的重量应为26.70 GB,但似乎正在发生一些延迟。当我添加一个时,懒惰立即停止,我的程序挂起,并且它们得到一个MemoryError。
我想知道引擎盖下是如何做的。
我看了一眼numpy.core.multiarray,发现numpy/core/src/multiarray/multiarraymodule.c下面这段代码似乎是空的定义:
static PyObject *
array_empty(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"shape","dtype","order",NULL};
PyArray_Descr *typecode = NULL;
PyArray_Dims shape = {NULL, 0};
NPY_ORDER order = NPY_CORDER;
npy_bool is_f_order;
PyArrayObject *ret = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&", kwlist,
PyArray_IntpConverter, &shape,
PyArray_DescrConverter, &typecode,
PyArray_OrderConverter, &order)) {
goto fail;
}
switch (order) {
case NPY_CORDER:
is_f_order = NPY_FALSE;
break;
case NPY_FORTRANORDER:
is_f_order = NPY_TRUE;
break;
default:
PyErr_SetString(PyExc_ValueError,
"only 'C' or 'F' order is permitted");
goto fail;
}
ret = (PyArrayObject *)PyArray_Empty(shape.len, shape.ptr,
typecode, is_f_order);
PyDimMem_FREE(shape.ptr);
return (PyObject *)ret;
fail:
Py_XDECREF(typecode);
PyDimMem_FREE(shape.ptr);
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何在C语言中实现这种惰性,以及在numpy中将在其他地方弹出。
注意,内核可以执行延迟分配。即malloc实际上并没有保留内存。第一次访问内存时,将发生页面错误,内核将执行实际分配(并可能决定只分配该页面的内存,而不分配整个数组)。
换句话说:C并不懒惰。延迟分配的是内核。
当您尝试向数组元素中添加一个数组时,会发生错误,因为该操作会修改所有内存位置,因此内核被迫实际上将所有数组放入内存中而失败。
我不是OS内存管理方面的专家,所以以上就是我所记得的OS课程。可以在这里找到一个参考。引用它:
另一方面,Linux严重损坏。默认情况下,它将对大多数内存请求回答“是”,以希望程序所要求的超出实际需求。
这就是说,即使所需的内存太大,内核也malloc几乎不会返回a NULL。它“希望”用户实际上不会使用他们请求的所有内存,这样他就可以避免加载某些页面并适合所需的数据。显然,这并不总是正确的。
| 归档时间: |
|
| 查看次数: |
429 次 |
| 最近记录: |