Каковы последствия вызова функций C API NumPy из нескольких потоков? - PullRequest
7 голосов
/ 05 декабря 2010

Это рискованный бизнес, и я понимаю, что Global Interpreter Lock - грозный враг параллелизма. Однако, если я использую C API NumPy (в частности, макрос PyArray_DATA в массиве NumPy), есть ли потенциальные последствия для его вызова из нескольких параллельных потоков?

Обратите внимание, что я все еще буду владельцем GIL и не буду выпускать его с поддержкой потоков NumPy . Кроме того, даже если NumPy не дает никаких гарантий о безопасности потоков, но на практике PyArray_DATA является потокобезопасным, для меня достаточно .

Я использую Python 2.6.6 с NumPy 1.3.0 в Linux.

1 Ответ

7 голосов
/ 05 декабря 2010

Отвечая на мой собственный вопрос здесь, но после поиска исходного кода для NumPy 1.3.0, я считаю, что ответ: Да, PyArray_DATA является поточно-ориентированным.

  1. PyArray_DATA определяется в ndarrayobject.h:

    #define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data))
    
  2. Тип структуры PyArrayObject имеет вид определено в том же файле; поле представляет интерес:

    char *data;
    

    Итак, теперь вопрос в том, является ли доступ к data из нескольких потоков безопасным или нет.

  3. Создание нового массива NumPy с нуля (т. Е. Не извлечение его из существующей структуры данных) передает указатель данных NULL в PyArray_NewFromDescr, определенный в arrayobject.c.

  4. Это вызывает PyArray_NewFromDescr для вызова PyDataMem_NEW, чтобы выделить память для поля data PyArrayObject. Это просто макрос для malloc:

    #define PyDataMem_NEW(size) ((char *)malloc(size))
    

В итоге, PyArray_DATA является поточно-ориентированным и до тех пор, пока массивы NumPy создаются отдельно, запись в них из разных потоков безопасна.

...