2013-03-26 3 views
1
for (n = 0; n < L_SUBFR; n++) 
{ 
    s = 0; 
    for (i = 0; i <= n; i++) 
    { 
     s += exc[i] * h1[n - i]; 
    } 
    y1[n] = s; 
} 

Optimzed версия:Оптимизация вложенных цикл

for (n = L_SUBFR; n != 0; n--) 
{ 
    for (i = n; i != 0; i--) 
    { 
     y1[n] = y1[n] + exc[i] * h1[n - i]; 
    } 
} 

Я бежал как коды на AMD opteron 6274 битной машине после компиляции с gcc 4.4.6. однако, я не могу видеть любой выигрыш в скорости или времени работы ,

(1) Можно ли каким-либо образом оптимизировать вышеуказанный код дальше?

(2) Может ли кто-нибудь сказать мне, почему я не могу получить прибыль?

+4

Зачем нужна вторая версия? Кроме того, они не имеют эквивалентной функциональности – SomeWittyUsername

+1

** Оставьте такую ​​оптимизацию компилятору ** (предполагая, что обе версии делают то же самое, что сомнительно). Компилятор для этого намного лучше, чем вы и я вместе. –

+0

Любой цикл, который вы можете сохранить во внутреннем цикле, полностью затухает циклами, проведенными в операторе присваивания 'y1'. Тогда цикл, который вы могли бы сохранить во внешнем цикле, * полностью * завален внутренним циклом. –

ответ

2

Вы должны сосредоточиться на создании читаемого кода, а не на «быстром» коде. Скорость достигается путем ваших алгоритмов более эффективными:

Вы получаете более высокую производительность, заменив наивные сорта с быстрой сортировкой, не заменяя (i != 0) с (i).

Компилятор делает все это для вас в любом случае.


Я резюмировать со ссылкой на обновленные вопросы, перечисленные:

(1) Есть ли способ, что я могу оптимизировать код выше в дальнейшем?

Конечно, вы можете заменить (i != 0) и (n != 0) с (i) и (n) и делать все виды махинаций и придирки с кодом, чтобы сделать это только немного быстрее, но в конце концов, вы на самом деле не меняется ничего потому что ваш компилятор делает еще больше оптимизаций. Часто он может оптимизировать сборку, сгенерированную напрямую.

(2) Может ли кто-нибудь сказать мне, почему я не могу получить прибыль?

Компилятор мой друг. Даже если компилятор здесь ничего не сделал, вы не заметите прирост, если у вас нет таймера с точностью до nano-second. В конечном счете, это зависит от вашего определения L_SUBFR.


Просто для Пинки, вот пример того, что компилятор может сделать:

unsigned int i = getValue(); 

if (i >= 10 && i <= 200) { 

} 

Это код, который кажется настолько минимален, поэтому неприводимым, может быть оптимизирована компилятором для этого:

unsigned int i = getValue(); 

if (i - 10 <= 190) { 

} 
+0

Просто nitpicking: компилятор не оптимизирует ассемблер, он оптимизирует некоторые внутренние представления (например, * Gimple * для GCC, чья версия 4.8 только что была выпущена) .... и преобразованные внутренние представления позже преобразуются в ассемблер (через некоторые другие представления, такие как RTL в GCC) –

+0

Я думаю, это звучит более выполнимо, я имею в виду, сколько вам придется заплатить программисту, чтобы сделать оптимизатор для кода сборки напрямую? : D –

+0

@ Magtheridon96 В плане 9 есть один. В Plan 9 объектный файл - это всего лишь «двоичный ассемблер». Компилятор делает некоторую оптимизацию сборки, такую ​​как выбор команды. – fuz

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