Проблема оптимизации из-за кэша L1 с NumbaPython

Программы на Python
Anonymous
Проблема оптимизации из-за кэша L1 с Numba

Сообщение Anonymous »

Я работал над оптимизацией расчета различий между элементами в массивах NumPy. Я использовал Numba для повышения производительности, но получаю скачок в 100 микросекунд, когда размер массива превышает 1 МБ. Я предполагаю, что это связано с размером кэша L1 моего процессора Ryzen 7950X 1 МБ.
Вот пример кода:

Код: Выделить всё

@jit(nopython=True)
def extract_difference_1(random_array):
shape0, shape1 = random_array.shape
difference_arr = np.empty((shape0, shape1), dtype=np.float64)
for i in range(shape0):
difference_arr[i] = random_array[i,0] - random_array[i,1], random_array[i,1] - random_array[i,2], random_array[i,2] - random_array[i,3], random_array[i,3] - random_array[i,4], random_array[i,4] - random_array[i,5], random_array[i,5] - random_array[i,6], random_array[i,6] - random_array[i,0]

return difference_arr

@jit(nopython=True)
def extract_difference_2(random_array):
shape0, shape1 = random_array.shape
split_index = shape0 // 2
part_1 = extract_difference_1(random_array[:split_index])
part_2 = extract_difference_1(random_array[split_index:])

return part_1 , part_2

x_list = [18500, 18700, 18900]
y = 7
for x in x_list:
random_array = np.random.rand(x, y)
print(f"\nFor (x,y) = ({x}, {y}), random_array size is {array_size_string(random_array)}:\n")
for func in [extract_difference_1, extract_difference_2]:
func(random_array) # compile the function
timing_result = %timeit -q -o func(random_array)
print(f"{func.__name__}:\t {timing_result_message(timing_result)}")
Результаты синхронизации:

Код: Выделить всё

For (x,y) = (18500, 7), random_array size is 0.988 MB, 1011.72 KB:

extract_difference_1:    32.4 µs ± 832 ns,   b: 31.5 µs,    w: 34.3 µs,     (l: 7, r: 10000),
extract_difference_2:    33.8 µs ± 279 ns,   b: 33.5 µs,    w: 34.3 µs,     (l: 7, r: 10000),

For (x,y) = (18700, 7), random_array size is 0.999 MB, 1022.66 KB:

extract_difference_1:    184 µs ± 2.15 µs,   b: 181 µs,     w: 188 µs,  (l: 7, r: 10000),
extract_difference_2:    34.4 µs ± 51.2 ns,  b: 34.3 µs,    w: 34.5 µs,     (l: 7, r: 10000),

For (x,y) = (18900, 7), random_array size is 1.009 MB, 1033.59 KB:

extract_difference_1:    201 µs ± 3.3 µs,    b: 196 µs,     w: 205 µs,  (l: 7, r: 10000),
extract_difference_2:    34.5 µs ± 75.2 ns,  b: 34.4 µs,    w: 34.6 µs,     (l: 7, r: 10000),
Разделение полученного значения Different_arr на два помогает, но я предпочитаю, чтобы результат представлял собой один массив. Тем более, что позже я увеличу y до 10, 50, 100, 1000 и x до 20 000. При объединении разделенных массивов part_1 и part_2 в Difference_arr я обнаружил, что это медленнее, чем Extract_difference_1. Я думаю, что замедление связано с тем, что extract_difference_1 превышает 1 МБ, в результате чего кеш L1 не используется.
Есть ли способ сохранить производительность, при этом результатом будет один массив с Python, Numba или любым другим пакетом? Или есть способ, который позволит мне повторно объединить эти массивы без снижения производительности из-за того, что полученный массив превысит размер кэша L1?

Подробнее здесь: https://stackoverflow.com/questions/786 ... with-numba

Вернуться в «Python»