realeugeneХорошо, специально для Вас уточню: слова выше "хорошим компилятором" читать как "хорошо оптимизирующим компилятором". Плохо (или совсем не) оптимизирующий компилятор сюда не подпадает.
Чтобы подглядывать в генерируемый код (с чем я абсолютно согласен) надо хоть немного разбираться в целевой архитектуре. Не все это знают и не всем это интересно, есть чисто алгоритмические приёмы оптимизаций (и вынос инваринта цикла за тело цикла к ним относится). Чтобы такой код стал выполняться
хуже надо очень постараться.
Кстати, раз уж всё равно стал отвечать, добавлю:
2) Если массивы используются вместе имеет смысл объединить их в один вектор структур или пар, чтобы обрабатываемые данные не валялись в разных местах памяти.
это не всегда хорошо работает, иногда сложность вычисления адресов съедает выигрыш от data prefetch
(пример: проход по массиву 100 байтных записей я бы сделал на указателе на начало записи и смещении внутри записи, как это реализует компилятор я не знаю и не знаю как это ему порегулировать, надеюсь хоть не будет для каждого поля вычислять заново и начальный адрес всей записи - а я видел и такое вживую) или некоторые поля записи не всегда нужны и их чтение зря расходует объём кэша и трафик памяти. Но это уже довольно тонкие вопросы, которые многим проще оценить на практике, чем вникать в ассемблерный код и архитектуру процессора.
Для пар же простых (и лучше одинаковых) типов, да и во многих других простых случаях, совет работает хорошо.