Почему умножение матриц выполняется быстрее с numpy, чем с ctypes в Python?

Я пытался найти самый быстрый способ умножения матриц и пробовал 3 разных способа:

  • Реализация на чистом питоне :Никаких сюрпризов.
  • Реализация Numpy с использованиемnumpy.dot(a, b)
  • Взаимодействие с C с использованием модуля ctypesв Python.

Это код C, преобразованный в разделяемую библиотеку:

#include <stdio.h>
#include <stdlib.h>

void matmult(float* a, float* b, float* c, int n) {
    int i = 0;
    int j = 0;
    int k = 0;

    /*float* c = malloc(nay * sizeof(float));*/

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            int sub = 0;
            for (k = 0; k < n; k++) {
                sub = sub + a[i * n + k] * b[k * n + j];
            }
            c[i * n + j] = sub;
        }
    }
    return ;
}

И код Python, вызывающий ее:

def C_mat_mult(a, b):
    libmatmult = ctypes.CDLL("./matmult.so")

    dima = len(a) * len(a)
    dimb = len(b) * len(b)

    array_a = ctypes.c_float * dima
    array_b = ctypes.c_float * dimb
    array_c = ctypes.c_float * dima

    suma = array_a()
    sumb = array_b()
    sumc = array_c()

    inda = 0
    for i in range(0, len(a)):
        for j in range(0, len(a[i])):
            suma[inda] = a[i][j]
            inda = inda + 1
        indb = 0
    for i in range(0, len(b)):
        for j in range(0, len(b[i])):
            sumb[indb] = b[i][j]
            indb = indb + 1

    libmatmult.matmult(ctypes.byref(suma), ctypes.byref(sumb), ctypes.byref(sumc), 2);

    res = numpy.zeros([len(a), len(a)])
    indc = 0
    for i in range(0, len(sumc)):
        res[indc][i % len(a)] = sumc[i]
        if i % len(a) == len(a) - 1:
            indc = indc + 1

    return res

Готов поспорить, что версия, использующая C, была бы быстрее… и я бы проиграл ! Ниже мой бенчмарк, который вроде бы показывает, что я либо сделал это неправильно, либо что numpyтупо быстро:

benchmark

Я хотел бы понять, почему версия numpyбыстрее, чем версия ctypes, я даже не говоря о чистой реализации Python, поскольку это очевидно.

48
задан Charles Menguy 3 May 2012 в 16:36
поделиться