NumPy C API扩展导致过多的内存使用

2024-09-29 13:25:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经为NumPy编写了一个C扩展来加速我的一些计算,但是随着我反复调用这个函数,我的内存使用率越来越高。我将函数缩减为一个最小示例:

PyObject* memory_test_function(PyObject* self, PyObject* args)
{
    PyArrayObject *ang;
    int i;

    if (!PyArg_ParseTuple(args, "O", &ang)) return NULL;

    int L0 = (int) PyArray_DIMS(ang)[0];

    // ballooning memory usage 
    npy_intp final_out_dims[2] = {L0,1};
    PyObject *output_array;
    output_array = PyArray_SimpleNew(2, final_out_dims, NPY_FLOAT64);
    Py_INCREF(output_array);

    for (i=0;i<L0;i++) 
    {
        *(double *)PyArray_GETPTR2(output_array,i,0) = 
            tan(*(double *)PyArray_GETPTR2(ang,i,0));
    }

    return PyArray_Return(output_array);

    /* constant memory usage
    double sum=0.0;
    for (i=0;i<L0;i++) sum+=tan(*(double *)PyArray_GETPTR2(ang,i,0));
    return PyFloat_FromDouble(sum); */
}

这个问题似乎是由创建输出数组引起的,因为仅仅返回一个float而不创建array对象在内存中是恒定的。我怀疑INCREF/DECREF有问题,但我认为我做的一切都是正确的。重复调用这个函数(大约一百万次)会使内存使用率随着时间线性增加,这让我觉得有些东西没有被正确地垃圾收集。手动使用gc没有帮助。如果有什么明显的遗漏请告诉我!你知道吗


Tags: 函数内存outputreturnarrayintpyobjectdouble
1条回答
网友
1楼 · 发布于 2024-09-29 13:25:13

PyArray_SimpleNew呼叫(间接,可能)_Py_NewReference在引擎盖下。此函数用于将新创建的引用的引用计数设置为1。你知道吗

随后的Py_INCREF将ref计数增加到2,从而确保Python永远不会释放这个对象,即使对它的所有引用都不存在,因为它的引用计数永远不会降到0。你知道吗

Py_INCREF调用是不必要的,因为这里没有与任何其他对象共享引用,您只是在本地使用它,然后将它传递给调用者。你知道吗

相关问题 更多 >