Почему доступ к памяти на x86 будет медленнее при выравнивании по первым 4 байтам строки кэша?

При написании сообщения в блоге о невыровненном / выровненном прямом доступе к памяти я столкнулся с результатом, который я изо всех сил пытаюсь объяснить: если мой доступ к памяти выровнен по первым 4 байтам, я вижу ощутимую разницу в производительности в худшую сторону, когда структура данных вписывается в L1 кэш. В некоторых случаях другие местоположения на 20% быстрее.

В статье более подробно рассказывается об эксперименте и методе, но вот краткое изложение:

  1. Выделите блок памяти, который умещается в L1(32k на моем ноутбуке, используйте hwloc/ проверьте спецификации вашего процессора, чтобы узнать). Выровняйте блок по размеру кэша (обычно 64b, проверьте ваше оборудование). Распределение осуществляется заранее и не измеряется.
  2. Выполните итерацию по блоку памяти и запишите длинное (некоторое значение) в каждую строку кэша с заданным смещением (эффективно вызывая запись без выравнивания, если смещение не кратно 8)
  3. Переберите блок памяти и прочитайте с того же смещения и убедитесь, что значение соответствует ожидаемому.

Почему должна быть какая-то разница в производительности, когда смещение составляет 0-3?

Суть измеряемого кода (согласно запросу в комментарии):

for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
    Unsafe.putLong(address, value);
}
for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
   if (Unsafe.getLong(address) != value)
       throw new RuntimeException();
}

Где начальный адрес выровнен по кешу + смещение. Полный эксперимент доступен здесь:

0 ответов

Другие вопросы по тегам