Это определенно связано с отсутствием кэша. Чем больше промах, тем больше ухудшение производительности будет введено процессором. На самом деле в современном мире процессор работает намного быстрее, чем память. Если в настоящее время процессор может иметь тактовую частоту около 4 ГГц, память все еще работает с частотой ~ 0,3 ГГц. Это большой разрыв в производительности, который все еще продолжает расти. Введение кэша было вызвано желанием скрыть этот пробел. Без использования кеша современный процессор будет тратить огромное количество времени на ожидание данных из памяти и ничего не делать в это время. В дополнение к разрыву в производительности каждый доступ к памяти создает дополнительные задержки, связанные с возможным параллелизмом на шине памяти с другими процессорами и устройствами DMA, а также время, необходимое для обработки и маршрутизации запросов на доступ к памяти на стороне логики управления памятью процессора (проверка кэшей). на всех уровнях: преобразование виртуальных адресов в физические, что может включать в себя пропадание TLB с дополнительным доступом к памяти, передачу запросов на шину памяти и т. д.) и контроллер памяти (запрос маршрутизации от контроллера ЦП к шине памяти контроллера, возможное ожидание для завершения цикла обновления банка памяти и т. д.). Подводя итог, можно сказать, что необработанный доступ к памяти имеет действительно большие затраты по сравнению с попаданием в кэш L1 или доступом к регистру. Разница в стоимости сопоставима с разницей в стоимости доступа к данным в памяти и во вторичном хранилище (HDD).
Кроме того, стоимость доступа к памяти будет расти с переходом от процессора к памяти. Доступ L2 обеспечит больший штраф, чем доступ к регистрам L1 или ЦП, доступ L3 обеспечит штраф больше, чем доступ L2, и, наконец, доступ к памяти предоставит штраф больше, чем доступ к памяти. Например, вы можете сравнить стоимость доступа к данным на разных уровнях иерархии памяти в следующей таблице (взято из http://www.anandtech.com/show/4955/the-bulldozer-review-amd-fx8150-tested/6)
Сравнение задержки кэша / памяти
-----------------------------------------------------------
| |L1| L2| L3| Main Memory |
-----------------------------------------------------------
|AMD FX-8150 (3.6GHz) | 4| 21| 65| 195 |
-----------------------------------------------------------
|AMD Phenom II X4 975 BE (3.6GHz)| 3| 15| 59| 182 |
-----------------------------------------------------------
|AMD Phenom II X6 1100T (3.3GHz) | 3| 14| 55| 157 |
-----------------------------------------------------------
|Intel Core i5 2500K (3.3GHz) | 4| 11| 25| 148 |
-----------------------------------------------------------
В отношении вашего конкретного случая:
0x1669 561 mov ecx, dword ptr [eax+0x8]
0x166c 561 mov dword ptr [ebp-0x68], ecx 2.178s 1,614,000,000
0x1670 560 mov ecx, dword ptr [eax+0x8] 0.001s 4,000,000 /* confusing and looks like wrong report for me*/
0x1673 560 mov dword ptr [ebp-0x5c], ecx 1.193s 1,536,000,000
У вас есть штраф за разыменование значения Index в строке кода.
mov ecx, dword ptr [eax+0x8]
Обратите внимание, что это первый доступ к данным в каждом последующем узле вашего списка, до этого момента вы манипулируете только по адресу узла, но данные этого адреса и, следовательно, не имеют доступа к памяти.
Вы заявили, что используете динамический список, и это плохо с точки зрения вероятности попадания в кеш. Кроме того, я предполагаю, что у вас достаточно большой список, что означает, что у вас будет кэш, заполненный данными, к которым ранее обращались (узлы списка, к которым обращались на предыдущих итерациях), и почти всегда будет иметь место пропадание кеша или попадание в кеш только в кэш L3 во время доступа к Index на каждой новой итерации. Но обратите внимание, что при первом доступе к Индексу при каждом потере кэша при каждой новой итерации данные, возвращаемые из памяти, будут храниться в кэше L1. И при повторном доступе к Index во время той же итерации цикла вы получите низкую стоимость попадания в кэш L1!
Поэтому я надеюсь, что предоставлю вам подробный ответ на оба ваших вопроса.
В отношении правильности сообщения VTune о правильности. Я хочу защищать разработчиков Intel VTune. Конечно, современные процессоры являются очень сложными устройствами с множеством улучшающих ILP технологий на плате, включая конвейерную обработку, суперскаларирование, выполнение вне порядка, прогнозирование ветвлений и т. Д., И, конечно, это делает подробный анализ производительности на уровне команд более трудным и более ценным. Но такие инструменты, как VTune, разработаны с учетом особенностей процессора, и я верю, что они не настолько глупы, чтобы разрабатывать и предоставлять инструмент или функцию, которые не имеют никакого смысла. Более того, похоже, что разработчики из Intel, как никто другой, не имеют доступа к полному пониманию всех особенностей процессора, и никто другой не может учесть эти детали при проектировании и разработке профилировщика.