LINUX.ORG.RU

Нашел " хотя современные компиляторы оптимизируют код гораздо хуже, чем это может сделать программист вручную "


1

1

Собственно вот. http://ru.wikibooks.org/wiki/Ассемблер_в_Linux_для_программистов_C

В самом начале написано

При написании кода на ассемблере всегда следует отдавать себе отчёт в том, действительно ли данный кусок кода должен быть написан на ассемблере. Нужно взвесить все «за» и «против», хотя современные компиляторы оптимизируют код гораздо хуже, чем это может сделать программист вручную на ассемблере.

UPD. Так ли это? Потому что постоянно слышу что уже компилятор гораздо лучше человека.



Последнее исправление: knotri (всего исправлений: 3)

Конечно, ведь неспроста доступны в языках ассемблерные вставки - только для оптимизации. А вопрос где?

Bfgeshka ★★★★★
()

Компилятор выдает код лучше (эффективнее) плохого программиста, но иногда хороший программист может сделать лучше, чем компилятор. И делает!

amomymous ★★★
()
Ответ на: комментарий от Bfgeshka

Наверное для низкоуровневых операций. А в других местах надо писать так, чтобы компилятор не создавал бессмысленные циклы...

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Это скорее вопрос того, что нужно на обоих языках для этого писать с руками из плеч, а не из разных нехороших мест. Иначе что вставками, что без них - всё одно.

А оптимизации компилятора заменяют программиста средней руки - они не идеальны, но работают.

Bfgeshka ★★★★★
()

Товарищи, я дополню вопрос:

правда ли, что при работе с оптимизирующими компиляторами, следуя неким приёмам программирования, можно помочь оптимизатору сгенерить более лучший код?

anonymous
()

Отдельные куски кода — да, код в целом — не думаю.

А проблема в вставками в том, что даже имея сотни опыта за плечами, можно не учесть какой-нибудь маленькой фигни и просто испротить производительность

derlafff ★★★★★
()

Помнится тут когда-то, года 4 назад, был добротный срач о том, что программист со своим человечьим умишкой в принципе не способен производить на ассемблерном коде оптимизации, которые умеют современные компиляторы. Вроде там даже Саныч был ещё.

yoghurt ★★★★★
()

Товарищи я дополню вопрос:

А правда, что в наше время при некоторых задачах оптимизация более оправдана, чем покупка нового камня с over9000 ядрами?

ados ★★★★★
()
Последнее исправление: ados (всего исправлений: 1)
Ответ на: комментарий от ados

А правда, что в наше время при некоторых задачах оптимизация более оправдана, чем покупка нового камня с over9000 ядер?

Очевидно, что оптимизированный (с т.з. ассемблера) код на новом камне с овер9000 ядер тоже будет работать быстрее, чем неоптимизированный.

Другое дело, число ядер тут особо не повлияет - оно для других оптимизаций.

yoghurt ★★★★★
()
Ответ на: комментарий от ados

А правда, что в наше время при некоторых задачах оптимизация более оправдана, чем покупка нового камня с over9000 ядрами?

Правда конечно.

knotri
() автор топика

Тривиальные оптимизации он делает лучше.

Но он не превратит сортировку пузырьком в сортировку слиянием.

LongLiveUbuntu ★★★★★
()

Так ли это? Потому что постоянно слышу что уже компилятор гораздо лучше человека.

бывают разные ситуации. например, если надо распараллелить вычисления на SIMD, особенно если GCC под ARMv7/NEON, то явно же придется ручками на асме, ибо на сишных интринсиках кода получится еще больше чем на асме, а без асма или интринсиков код будет раз в 10 тормознее.

причем, под тот же ARM, GCC вообще всегда генерирует адский понос. даже без всяких SIMD. так что переписав на асме можно существенно много чего ускорить. в разы, в прямом смысле.

ну а если писать под x86[_64] и не нужен SIMD, то компиляторы обычно генерируют код хорошо, лучше большинства программистов.

waker ★★★★★
()
Ответ на: комментарий от yoghurt

ну чё ты прицепился, я имел ввиду просто смену на более мощную и современную машину.

Так если далее вдаваться в детали, то я слышал, что сейчас производительность задаётся производительностью оперативной памяти.

ados ★★★★★
()
Ответ на: комментарий от anonymous

Premature optimization is the root of all evil.

Порой бывает даже хуже. Банальный пример: все помнят, что менять местами целочисленные значения XOR'ом — это супрекруто и супероптимально. А вот фигушки. ;)

#include <stdio.h>

void
swap1(int *a, int *b)
{
        int c = *a; *a = *b; *b = c;
}

void
swap2(int *a, int *b)
{
        *a ^= *b; *b ^= *a; *a ^= *b;
}

int
main()
{
        int a = 7, b = 13;

        printf("%d %d\n", a, b);
        swap1(&a, &b);
        printf("%d %d\n", a, b);
        swap2(&a, &b);
        printf("%d %d\n", a, b);

        return 0;
}

И соответствующий выхлоп objdump:

0000000000000ca0 <swap1>:
 ca0:   8b 17                   mov    (%rdi),%edx
 ca2:   8b 06                   mov    (%rsi),%eax
 ca4:   89 07                   mov    %eax,(%rdi)
 ca6:   89 16                   mov    %edx,(%rsi)
 ca8:   c3                      retq   

0000000000000ca9 <swap2>:
 ca9:   8b 07                   mov    (%rdi),%eax
 cab:   33 06                   xor    (%rsi),%eax
 cad:   89 07                   mov    %eax,(%rdi)
 caf:   33 06                   xor    (%rsi),%eax
 cb1:   89 06                   mov    %eax,(%rsi)
 cb3:   31 07                   xor    %eax,(%rdi)
 cb5:   c3                      retq   

Т.ч. не надо пытаться быть умней компилятора (точнее тех людей, кто его писал).

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)

Почитай книжку «Техника оптимизации программ. Эффективное использование памяти», хоть и древняя и часть информации неактуально, но принципы остались теже.

fornlr ★★★★★
()
Ответ на: комментарий от fornlr

Почитай книжку «Техника оптимизации программ. Эффективное использование памяти»

Мне рано думать про оптимизацию. Мне пока бы научится придумывать алгоритмы с хорошей асимптотикой.

knotri
() автор топика
Ответ на: комментарий от fornlr

Техника оптимизации программ. Эффективное использование памяти
Эффективное использование памяти
памяти

Скорее даже вредно. Не забываем о Space-Time Tradeoff.

Раньше память была дорогая и такие финты ушами (в ущерб производительности) были оправданны. Теперь уже нет.

beastie ★★★★★
()
Ответ на: комментарий от fornlr

Каюсь, не читал, но осуждаю. ;) Просто это обычная проблема со старой литиратурой. Писалась она для совсем других условий. Это надо просто держать на заметке.

beastie ★★★★★
()
Ответ на: комментарий от yoghurt

Очевидно, что оптимизированный (с т.з. ассемблера) код на новом камне с овер9000 ядер тоже будет работать быстрее, чем неоптимизированный.

неочевидно, на самом деле

AptGet ★★★
()
Ответ на: комментарий от waker

причем, под тот же ARM, GCC вообще всегда генерирует адский понос. даже без всяких SIMD. так что переписав на асме можно существенно много чего ускорить. в разы, в прямом смысле.

можно пример?

AptGet ★★★
()
Ответ на: комментарий от AptGet

можно пример?

у меня нет примеров под рукой, но когда реализовывал эквалайзер для андроидного deadbeef - все это видел собственными глазами. для кода который руками на асме пишется в 2 инструкции - GCC генерирует штук 10. правда, это и было года 2 назад. может уже улучшили.

waker ★★★★★
()

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

Имхо, профессиональное развитие автора застряло году этак в 92-м.

ovk48 ★★★
()
Ответ на: Premature optimization is the root of all evil. от beastie

все помнят, что менять местами целочисленные значения XOR'ом — это супрекруто и супероптимально

Я не знаю, на каких курсах домохозяек этому учат, но вообще-то это добавляет зависимость по данных на современных процессорах, поэтому это плохо. Во-вторых, пишущие на асме скорее будут использовать xchg reg,reg, потому что это банально короче.

P. S. сходу не помню, меняет ли xor CF, потому что если он не перезаписывает флаги, то с xor-ами вообще содомия происходит.

anonymous
()

В случае маленького участка кода это справедливо. Чеовек-исследователь всегда может написать несколько различных реализацией, сравнить их с теми, что генерируют различные компиляторы, и выбрать лучшую.

Deleted
()

Оптимизаторы хорошо делают основную работу — common subexpression elimination, loop unrolling, instruction scheduling и прочие рутинные задачи, связанные с разбором сорца и его нормализацией для подачи в проц и кеши. В современных процах эта рутина еще и некисло сложная, так что здесь компилятор зарулит любого.

Оптимизаторы по дефолту не генерят SIMD, но генерят фреймы например, а также гарантируют выполнение условий, которые были [недо]описаны в коде. Например аргумент с restrict и без — совершенно разные вещи. Человек на ассемблере это подразумевает в уме, чаще просто не думая об этом, а на сях явно пишет (чаще просто *не* пишет).

Человек может ускорить нетривиальные пути, которые разработчики компилятора даже и не думали учитывать, например использовать тот же SIMD для хитрого сложения/вычитания/whatever массивов, т.к. такие задачи находятся на нечеткой грани оптимизация vs. выбор алгоритма, так что такое вряд ли когда-то будет. Лучше писать спецбиблиотеки отдельно от компилятора, чем встраивать их в него, что и делается.

И самое главное: никогда не надо писать «оптемезированный» код, ни на сях, ни на ассемблере. Даже ради спортивного интереса. Мало того, что его никто не сможет потом распарсить, так еще некоторые умудряются поднасрать оптимизатору вместо помощи. Нет «максемально быстрого кода», есть допустимые временные рамки и в случае их невыполнения — профайлер, который покажет горячие куски, которые чаще всего устраняются алгоритмически(!), а не переписыванием их на асме. А о негорячих кусках даже думать дорого. Например, недавно я писал парсер для ручных заметок, и он хорошенько притормаживал, но после nytprof'а стало ясно, что нужно переразбить регэкспы на частичные матчи и т.о. направить хотспоты в самые активные ветки — и это было нетривиально и зависело от инпута. Ускорилось в разы.

arturpub ★★
()
Ответ на: комментарий от knotri

алгоритмы с хорошей асимптотикой.

... и применять их при малом количестве входных данных

hvatitbanit
()

" хотя современные компиляторы оптимизируют код гораздо хуже, чем это может сделать программист вручную "

за это надо убивать!
это же каким дебилом надо быть, чтобы такое написать!??????

megabaks ★★★★
()
Последнее исправление: megabaks (всего исправлений: 1)

media-libs/jpeg сливает media-libs/libjpeg-turbo минимум в 1.5 раза даже на 32-х битах из-за ассемблерных вставок с SIMD в libjpeg-turbo.
где же эти волшебные опции, которые заставят первую опередить вторую!?
где же этот волшебный компилятор!?

megabaks ★★★★
()
Последнее исправление: megabaks (всего исправлений: 1)
Ответ на: комментарий от ados

Так если далее вдаваться в детали, то я слышал, что сейчас производительность задаётся производительностью оперативной памяти.

или шиной? в архитектуре фон неймана узкое место какраз шина между камнем и памятью

unt1tled ★★★★
()
Ответ на: Premature optimization is the root of all evil. от beastie

менять местами целочисленные значения XOR'ом — это супрекруто и супероптимально

это когда у тебя памяти нет на временную переменную, а так все давно знают, что такой подход сливает

unt1tled ★★★★
()
Ответ на: комментарий от hvatitbanit

тебе не дано понять истинный смысл сей авы.
да и факты я привёл, а ты пока только флудишь и обсираешься прилюдно.

megabaks ★★★★
()

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

Это абсолютная ложь.

уже компилятор гораздо лучше человека

Это тоже.

Истина посередине. Пример из жизни: как-то я писал библиотеку графических фильтров - начал из интереса на асме, потом запарился с одним сложным и написал его на C, потом из интереса переписал всё остальное на C, после чего логично было сравнить скорость. Так вот от фильтра к фильтру ситуация была диаметрально противоположной: на одних абсолютно наивный ассемблерный код давал преимущество в несколько раз над скомпилированным C, на других сколько я не бился у меня близко не получалось приблизить скорость ассемблерного кода к скомпилированному.

А вообще вопрос ASM vs. C смысла не имеет. Если вы его задаёте, вы гарантированно неопытны и рано вам ещё писать на ассемблере.

  • На первом месте всегда переносимость и поддерживаемость кода
  • Куда большего выигрыша по производительности почти гарантированно можно достичь не прибегая к ассемблеру
    • Выбором более подходящего вычислителя. Курим GPU.
    • Алгоритмически. Курим асимптотику алгоритмов.
    • Распараллеливанием кода.
    • Нет, ГРАМОТНЫМ распараллеливанием кода. Вспоминаем закон Амдала, курим contention, lockfree и вообще независимость по данным
    • Хочется ниже уровнем? Вспоминаем что самая медленная деталь компьютера - память. Курим cache locality и смежные темы
    • Хочется ещё ниже? Курим simd интринсики

      Напомню, это всё оставаясь в рамках высокоуровнего, переносимого и поддерживаемого кода.

  • Есть шанс что вы не перегоните компилятор, а время потратите
  • А, вообще говоря, боттлнек-то который подлежит оптимизации вы найти способны?
  • А в производительности ли вообще проблема вашего продукта?

Итого, довольно часто можно написать на ассемблере быстрее. Но крайне маловероятно что вам это что-то даст, во-первых, по факту (осилите найти правильное место, осилите действительно заметно увеличить его производительность, осилите оценить кому эта производительность вообще нужна), во-вторых, с учётом альтернатив (за то же время можно более эффективно оптимизировать без ассемблера, либо сделать более полезную пользователям фичу). А с учётом того что вы всего вышеперечисленного не знаете (иначе не задали бы вопрос) - вы не осилите, не осилите, не осилите, потратите кучу времени ни на что, произведёте полурабочий говнокод, потеряете мотивацию и угробите проект не сэкономив ни такта ещё задолго до того как сменится поколение процессоров и ваш ассемблер перестанет быть эффективнее даже в теории.

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

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от hvatitbanit

факт остаётся фактом - компилятор слил прямым рукам.
по этой причине и в lzma ручной asm
но ты продолжай флудить, малыш.
чмоки на счастье.

megabaks ★★★★
()
Ответ на: комментарий от slovazap

сколько я не бился у меня близко не получалось приблизить скорость ассемблерного кода к скомпилированному

Может я чего то не понимаю, а посмотреть ассемблерный код скомпилированного Сишного и понять где теряется скорость?

Если вы его задаёте, вы гарантированно неопытны и рано вам ещё писать на ассемблере.

Я и не говорил что хочу писать на ассемблере, я хочу научится «читать». Фрагменты кода. Ну и так, для общего развития.

knotri
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.