Вы пытались развернуть цикл?
- Я бы не стал беспокоиться о промахах L1 прямо сейчас. Также один L2 пропустил 1224 раза в порядке, процессор должен загрузить значения в кеш в какой-то момент.
- Какой процент пропусков L2 составляет этот код по сравнению с остальной частью программы?
- Используйте calloc(), если размер массива всегда один и тот же, и вы используете константы для размера, тогда компилятор может оптимизировать нулевое значение массива. Также единственное, что могло бы повлиять на использование строк в кешках, - это выравнивание, а не то, как оно было инициализировано.
Редактировать: Число, где трудно читать этот путь и читать их неправильно в первый раз.
позволяет убедиться, что я читаю номера прямо на линии 5:
Ir 146,880
I1mr 1,224
ILmr 1
Dr 48,960
D1mr 0
DLmr 0
Dw 24,480
D1mw 0
DLmw 0
L1 кэш разделяется на два 32KByte кэширует один для кода I1 и один из данных D1. IL & DL - это кеш L2 или L3, который совместно используется как данными, так и инструкциями.
Большое количество I1mr - это команда пропускает не пропуски данных, это означает, что код цикла выталкивается из кеша инструкций I1.
I1 промахивается по строке 1 & 5 всего 3672, что составляет 3 раза 1224, поэтому каждый раз, когда цикл запускается, вы получаете 3 промаха кэша I1 с линиями кеша 64 бит, что означает, что размер кода цикла составляет 128-192 байта для покрытия 3 строки кэша. Таким образом, те I1 промахиваются в строке 5, потому что именно здесь код цикла пересекает последнюю строку кэша.
I would recommend using KCachegrind for viewing the results from cachegrind
Edit: Подробнее о строках кэша.
Этот код цикла не похож на то, что он сам вызывает 1224 раза, поэтому это означает, что есть больше кода, который выталкивает этот код из кеша I1.
Ваш кеш I1 объемом 32 Кбайт разделен на 512 строк кэша (по 64 байта). Компонент «8-позиционная ассоциативная» означает, что каждый адрес памяти отображается только 8 из этих 512 строк кэша. Если вся ваша программа - это один непрерывный блок размером 32 Кбайт памяти, то все они будут вписываться в кеш I1, и ни один из них не будет удален. Вряд ли это не так, и будет храниться более 8 64-битных блоков кодирования кода для тех же 8 строк кеша. Допустим, что вся ваша программа имеет 1 Мбайт кода (включая библиотеки), тогда каждая группа из 8 строк кэша будет иметь около 32 (1 Мбайт/32 Кбайт) фрагментов кода для тех же 8 строк кеша.
Read this lwn.net article for all the gory details about CPU caches
компилятор не всегда может определить, какие функции программы будут горячие точки (так называемый много много раз) и который будет codespots (т.е. код обработчика ошибок, которые почти никогда не работает). GCC имеет атрибуты функций hot/cold, которые позволят вам отмечать функции как горячие/холодные, это позволит компилятору группировать горячие функции вместе в одном блоке памяти, чтобы улучшить использование кеша (например, холодный код не будет вызывать горячий код из кэша).
В любом случае эти промахи I1 действительно не стоят времени беспокоиться.
A. Это нормально, но почему в строке 5 отсутствуют пропуски кеша, тогда как в строке 3 меньше. 4. Нужно ли самому определять предмет выравнивания, я читал, что malloc по умолчанию обеспечивает выравнивание по 8/16 байт , – anup
Да, malloc должен обеспечивать выравнивание по 8 байт, но это не то же самое, что выравнивание кеша 64Byte. Выравнивание кеша важно только тогда, когда у вас есть массив объектов по 64 байта каждый. Если в массиве не выделен кеш, то доступ к любому одному элементу массива может привести к двум промахам в кэше вместо одного. Но выравнивание кеша не является проблемой в этом случае. – Neopallium
Спасибо за ваш ответ. Но, одна вещь, что я не понял, что это касается 3 строк кэша? Должно быть больше строк кеша. – anup