Я изучаю поведение кэширования на разных языках. Я создаю две матрицы в python, используя списки (да, я знаю, что это связанный список, но со мной здесь). Затем я перемножить эти матрицы вместе тремя способами:Умножение и кеширование матрицы Python
def baseline_matrix_multiply(a, b, n):
'''
baseline multiply
'''
c = zero_matrix(n)
for i in range(n):
for j in range(n):
for k in range(n):
c[i][j] += a[i][k] * b[k][j]
return c
def baseline_matrix_multiply_flipjk(a, b, n):
'''
same as baseline but switch j and k loops
'''
c = zero_matrix(n)
for i in range(n):
for k in range(n):
for j in range(n):
c[i][j] += a[i][k] * b[k][j]
return c
def fast_matrix_multiply_blocking(a, b, n):
'''
use blocking
'''
c = zero_matrix(n)
block = 25;
en = int(block * n/block)
for kk in range(0, en, block):
for jj in range(0, en, block):
for i in range(n):
for j in range(jj, jj + block):
sum = c[i][j]
for k in range(kk, kk + block):
sum += a[i][k] * b[k][j]
c[i][j] = sum
return c
Мои тайминги заключаются в следующем:
Baseline:
3.440004294627216
Flip j and k:
3.4685347505603144
100.83% of baseline
Blocking:
2.729924394035205
79.36% of baseline
Некоторые вещи, чтобы отметить:
Я знаком с поведением кэширования процессора. Чтобы увидеть мой эксперимент в C, см. here, хотя я не получил никаких отзывов.
Я сделал это в Javascript и C# и функция флип-JK обеспечивает значительный прирост производительности, используя массивы (JS работать на хром браузер)
реализация Python является Python 3.5 путем Anaconda
Пожалуйста, не говорите мне о numpy. Мой эксперимент - это не абсолютная производительность, а понимание поведения кеширования.
Вопрос: Каждый знает, что здесь происходит? Почему flip-j-k не обеспечивает ускорение? Это потому, что это связанный список? Но почему же блокирование обеспечивает не-маргинальное улучшение производительности?
«да, я знаю, что это связанный список, но неся со мной здесь» - на самом деле это не так. Он реализован с помощью динамически измененного массива, такого как Java ArrayList или вектор C++. – user2357112
Мне интересно, не выгодно ли кэширование с помощью индексации доступа и проверки границ. В последнем случае вы выбрали «кеш» целевое значение, уменьшив на 30% индексированные обращения. –
@ user2357112 Я стою исправленный. Они динамически изменяют размеры массивов, но на самом деле они в конечном итоге представляют собой массив указателей на фактические элементы? Сами элементы не хранятся в памяти постоянно? Вот что я понимаю из https://docs.python.org/3/faq/design.html#how-are-lists-implemented –