Расчет количества циклов под Linux - PullRequest
0 голосов
/ 19 марта 2012

У меня есть ассемблерный код, который в 100 раз превосходит эти две инструкции:

    movl    %eax, -16(%rbp)
    movl    -12(%rbp), %eax

, который соответствует этому циклу кода c:

 int i;
    int a=5, b;
    for (i=0 ; i < sptr->numberOfIterations ; i += 100){
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a; // 100 assignments 
    }

Почему операция b = a;перейти к двум инструкциям?и как получается, что я рассчитываю, сколько циклов (каждый b=a;) занимает один цикл?

Я скомпилировал его с g++

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

Вы должны дать компилятору возможность оптимизировать код. С правильными флагами оптимизации -O3 -march=native мой компилятор (gcc) может сократить все это до следующей строки:

movl    $5, %eax

без цикла, повторение кода, ничего.

Таким образом, ваш компилятор может выполнять или не выполнять оптимизацию и многое, чего вы не видите. И процессоры разные. Мой здесь может поместить константу 5 в мгновение и вообще не создает переменную a.

3 голосов
/ 19 марта 2012

b = a принимает две инструкции: сначала переместите значение a в регистр, затем переместите значение этого регистра в адрес памяти b:

movl    %eax, -16(%rbp) // move a's value to eax
movl    -12(%rbp), %eax // move eax's value into b's address.

Поскольку вы повторяете эту инструкцию снова и снова, компилятор понимает, что один b=a будет таким же, как и 100. Поэтому он просто сводит цикл for в одну b=a инструкцию.

РЕДАКТИРОВАТЬ : поскольку вы говорите, что эти строки появляются 100 раз, компилятор выполняет без оптимизации для вашего кода.Результат ASM вашего кода в точности соответствует тому, что вы написали, 100 раз b=a.

1 голос
/ 19 марта 2012

Под любым разумным компилятором с разумными настройками оптимизации, этот код:

int i;
int a=5, b;
for (i=0 ; i < sptr->numberOfIterations ; i += 100){
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a; // 100 assignments 
}

Будет оптимизировано в:

int i;
for (i=0; i < sptr->numberOfIterations; i += 100); // Possibly further reduced from O(n) into O(1).
int a = 5;
int b = 5;

Или, если i, a и b никогда не используются, компилятор может оптимизировать его так:

;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...