Зачем изучать Тайники?
Позвольте мне сначала представить очень простую задачу добавления скаляра к каждому элементу двумерной матрицы. Есть два способа, которыми я могу это сделать:
- Доступ к элементам по строкам
function rowAccess(A::AbstractMatrix)
for i in 1:size(A)[1]
for j in 1:size(A)[2]
A[i,j] = A[i,j]+1
end
end
return A
end
- Доступ к элементам по столбцам
function colAccess(A::AbstractMatrix)
for i in 1:size(A)[1]
for j in 1:size(A)[2]
A[j,i] = A[j,i]+1
end
end
return A
end
› Я буду использовать язык программирования Julia, но вы можете использовать любой другой язык программирования.
Когда я запускаю оба из них независимо (поставляя 5000 на 5000) матрицу A
) и тестирую ее, я наблюдаю, что функция rowAccess
выполняется 160,2 мс, а colAccess
завершается через 16,4 мс!!
@btime _ = colAccess(A); 16.400 ms (0 allocations: 0 bytes)
@btime _ = rowAccess(A); 160.207 ms (0 allocations: 0 bytes)
Оба эти результата можно легко объяснить после хорошего понимания кэшей, поэтому крайне важно, чтобы каждый программист понимал, как память работает в современных компьютерах. В этом сообщении блога я объясню основные понятия, связанные с иерархией памяти, чтобы вы могли приступить к написанию кода дружественного к кэшированию и избежать ошибок, таких как ошибка в функции rowAccess
. .
Если вы попытаетесь сделать то же самое на C/C++, вы заметите, что доступ к строкам выполняется быстрее, чем доступ к столбцам. Не волнуйтесь, это нормально, и к концу этого поста у вас будет ответ и на этот вопрос.
Для полного сообщения в блоге перейдите по следующей ссылке: https://tgautam03.github.io/2021/10/31/CacheBasics/
Первоначально опубликовано на https://tgautam03.github.io 31 октября 2021 г.