Я прочитал этот вопрос и ответ - Cython nogil с ThreadPoolExecutor не дает ускорений , и у меня похожая проблема с моим кодом Cython, не получающим ускорение, которое ожидается, несмотря на то, что моя система имеет несколько ядер. У меня есть 4 физических ядра на экземпляре Ubuntu 18.04, и если я сделаю количество заданий равным 1 в приведенном ниже коде, он будет работать быстрее, чем когда я его создаю. %. Я выполняю поиск структуры данных в классе C ++, который не изменяется, т. Е. Я делаю запросы только для чтения к структуре данных C ++ через Cython. На стороне C ++ нет блокировок мьютекса.
Это мой первый опыт работы с GIL, и мне интересно, правильно ли я его использовал. Кроме того, вывод времени немного сбивает с толку, так как я не думаю, что он правильно отображает фактическое время, затраченное каждым из рабочих потоков.
Кажется, я упустил что-то важное, но не могу понять, что это такое, поскольку я в значительной степени использовал тот же шаблон для использования GIL, как видно из связанного ответа SO.
import psutil
import numpy as np
from concurrent.futures import ThreadPoolExecutor
from functools import partial
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int)
int x0, y0, x1, y1
int getArea() nogil
cdef class PyRectangle:
cdef Rectangle *rect
def __cinit__(self, int x0, int y0, int x1, int y1):
self.rect = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.rect
def testThread(self):
latGrid = np.arange(minLat,maxLat,0.05)
lonGrid = np.arange(minLon,maxLon,0.05)
gridLon,gridLat = np.meshgrid(latGrid,lonGrid)
grid_points = np.c_[gridLon.ravel(),gridLat.ravel()]
n_jobs = psutil.cpu_count(logical=False)
chunk = np.array_split(grid_points,n_jobs,axis=0)
x = ThreadPoolExecutor(max_workers=n_jobs)
t0 = time.time()
func = partial(self.performCalc,maxDistance)
results = x.map(func,chunk)
results = np.vstack(list(results))
t1 = time.time()
print(t1-t0)
def performCalc(self,maxDistance,chunk):
cdef int area
cdef double[:,:] gPoints
gPoints = memoryview(chunk)
for i in range(0,len(gPoints)):
with nogil:
area = self.getArea2(gPoints[i])
return area
cdef int getArea2(self,double[:] p) nogil :
cdef int area
area = self.rect.getArea()
return area