2017-01-06 2 views
0

Какая версия более эффективна и почему? Кажется, что оба делают одни и те же вычисления. Единственное, о чем я могу думать, это то, что компилятор признает, что в (a) j не изменяет значение и не требует его вычисления снова и снова. Любой вход будет отличным!У кого лучше доступ к памяти? (C++)

#define M /* some mildly large number */ 
double a[M*M], x[M], c[M]; 
int i, j; 

(a) First version 
for (j = 0; j < M; j++) 
    for (i = 0; i < M; i++) 
     c[j] += a[i+j*M]*x[i]; 

(b) Second version 
for (i = 0; i < M; i++) 
    for (j = 0; j < M; j++) 
     c[j] += a[i+j*M]*x[i]; 
+2

Узнайте, измерив его на целевом компьютере. –

+0

@PaulR: Подлинный вопрос - могут ли современные компиляторы не определять это и менять преамбулы цикла? Видя, как семантика одинакова. –

+0

@LightnessRacesinOrbit: да, некоторые компиляторы могут выполнять переупорядочение каналов, по крайней мере для некоторых простых случаев, таких как это. –

ответ

5

Речь идет о шаблонах доступа к памяти, а не о вычислительной эффективности. В общем случае (a) происходит быстрее, поскольку он обращается к памяти с шагом блока, который намного более эффективен с точки зрения кэша, чем (b), который имеет шаг M. В случае (a) каждая линия кэша полностью используется, тогда как с (b) возможно, что из каждой строки кэша будет использоваться только один элемент массива до его выселения,

Сказав это, некоторые компиляторы могут выполните оптимизацию переупорядочения циклов, так что на практике вы не увидите никакой разницы, если это произойдет. Как всегда, вы должны проверить или прокомментировать свой код, а не просто гадать.

+1

У меня никогда не было начального шага. Я читаю об этом сейчас в Википедии. Спасибо за ваш ответ :) – Samu

+0

«Шаг блока» эффективно просто означает «последовательно» или «смежно» в этом контексте. –

+2

@Samu: Буквально «шаг за шагом». Это как собирать предметы по порядку, когда вы идете по проходу супермаркета, а не получаете что-то с полки 1, а затем идите, чтобы получить что-то с полки 10, а затем идите на полку 2, а затем идите к полке 11 ... В этом аналог, ваш компьютер действительно поднял все с полки 1-10, чтобы начать с того, что вы могли бы затем вишнево выбрать то, что вы хотели, даже не делая никакой ходьбы! А теперь он должен забрать все с полок 1-10, потом все с полок 11-20, потом все с полки 1-10 снова ... –

Смежные вопросы