Оптимизирует ли оптимизатор последовательное обращение к массиву ссылок?
Вопрос касается всех существующих языков программирования.
Когда мы идём по массиву последовательно, это работает максимально быстро благодаря кэшам CPU. Но допустим это массив ссылок/объектов/etc. Внутри цикла мы вначале берём ссылку последовательно, но сама ссылка может вести в рандомное место памяти. Если мы внутри итерации цикла обращаемся к значению по этой ссылке, получается, процессору придётся ждать, пока значение не будет получено из памяти (предполагается, что объём используемой памяти большой).
Конечно, это легко пофиксить — мы можем обращаться к значению не по текущей ссылке, а к значению, полученному на предыдущей итерации цикла, ведь с начала момента обращения к этому значению уже прошло много времени, и нужная область памяти уже должна находиться в кэше. При этом в момент работы с этим значением будет читаться область памяти по текущей ссылке (благодаря распараллеливанию команд). Получается, мы проводим вычисления как бы бесплатно.
Вопрос: существуют ли компиляторы (в любых языках программирования), которые проводят такую оптимизацию? Либо же правда в том, что на самом деле оптимизация не требуется по каким-то причинам?
PS. Конечно же понятно, что даже если не оптимизирует, миллионов 100 обращений в секунду, думаю, процессор может сделать — редко это станет узким горлышком. Вопрос скорее из любопытства.
Сергей Горностаев, упреждающее чтение возможно только при последовательном доступе. Если у нас есть 1 ГБ данных, к которым мы обращаемся рандомно, то я сомневаюсь, что процессор сможет это оптимизировать… (хотя не факт).
Фишка в том, что мы не совсем рандомно обращаемся, по факту следующий рандомный элемент известен заранее. Вот и интересно, насколько хорошо такие вещи оптимизируются или в случае чего лучше самому соптимизировать.
vitaliy2, я уже давно не пишу на ассемблере и сейчас больше строю предположения, но на уровне команд процессора обращение по ссылке - это, грубо говоря, последовательность операций в виде загрузки адреса ссылки в пары регистров и/или стек и прерывания/системного вызова. Как только такая последовательность появится в конвейере, процессор может предсказать её выполнение и может заранее начать загрузку в кэш данных по этой ссылке.
Сергей Горностаев, спасибо, если так подумать, у нас есть команда взятия значения по адресу, значение которого находится по другому адресу. И в цикле мы вначале выполняем эту команду допустим, для (внешнего) адреса 1000, потом для 1001, потом для 1002, и логично, что мы выполним эту команду также и для 1003, 1004 и т. д. Ну или как-нибудь аналогично по последовательности команд, как Вы сказали.
Получается, теоретически процессор может предсказать такие рандомные обращения к памяти, потому что их вызывает явно не рандомный код.