Вопрос по оптимизации программы

Тема в разделе "WASM.A&O", создана пользователем Santaev, 29 янв 2007.

  1. Santaev

    Santaev New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    29
    В одной программе встретил такой фрагмент (почти вся программа в таком стиле написана):

    Код (Text):
    1.   fast:=0;
    2.     slow:=0;
    3.     for i:=10 to 50 do  fast:=fast+inpp[i]/40;
    4.     for i:=75 to 85 do   slow:=slow+inpp[i]/10;
    Вопрос: современные компиляторы превратят это в оптимальный код???
    Или все-таки быстрее как меня в молодости учили:
    Код (Text):
    1.   fast:=0;
    2.     slow:=0;
    3.     for i:=10 to 50 do  fast:=fast+inpp[i];
    4.     fast:=fast/40;
    5.     for i:=75 to 85 do   slow:=slow+inpp[i];
    6.     slow:=slow/10;
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Результат может отличаться, если числа в массиве большие, т.е. если при сложении может произойти переполнение.
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Дельфи - точно оставит как есть, другие - не знаю. Но судя по бытующему мнению все или по кр.мере большинство известных компиляторов плохо оптимизируют (если не сказать вообще не оптимизируют FPU-код). Компилятор не только "не соображает" заменить деление умножением на обратную величину или вообще вынести деление или умножение за цикл, но еще и "боится" копить сумму в регистре и на каждой итерации сохраняет ее в память и на следующем шаге грузит заново :dntknw:
    Если кодишь на дельфи, то попробуй заменить цикл на fast:=Sum(inpp)*0.025 и посмотри во сколько раз будет быстрее. Sum это оптимизированная ассемблерная функция из Math.pas, которая копит параллельно 4 частичные суммы в регистрах FPU без промежуточных сохранений. Одно только такое распараллеливание дает увеличение скорости до 3-4 раз по сравнению с накоплением в одном регистре, не говоря уж о ненужных загрузках\выгрузках.
    Одним словом асм рулит, особенно на FPU-вычислениях ;)

    PS: Кстати на современных компах циклы fast:=fast+inpp и fast:=fast+inpp*0.025 (по кр.мере если держать 0.025 в регистре) будут выполняться примерно за одно и то же время, т.к. throughput (темп) независимых fmul составляет 1-2 такта, а латентность зависимых fadd - 3-6 тактов в завис-ти от проца. По этой же причине и накопление частичных сумм рулит
     
  4. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Не надо путать компилятор и маткад. Оптимизатор делает как правило мелочи или те вещи которые тебе не доступны из-за высокого уровня языка. А вмешиваться в сам алгоритм он не обязан, каким-бы крутым он небыл...