Недавно писал одну небольшую утилиту для обработки неких данных. Программа преобразует один входной бинарный поток в другой бинарный поток, попутно проводя некие вычисления над потоком(подсчет CRC). Старался добиться максимальной скорости. Скорость я считал только для внутреннего цикла, который и выполнял всю основную работу, т.е. не учитывал ввода-вывода при подсчете скорости.
Несколько наблюдений:
1. Подход: "сделать все на адских C++ шаблонах — компилятор потом оптимизирует" не работает, если нужно добиться максимальной скорости. Переписал на макросах — заработало заметно быстрее. Одна функция заработала быстрее на 50%.
2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
3. Попробовал скомпилировать компилятором Интел C++. Скорость работы упала(!sic) на 30%(!sic) по сравнению с программой откомпилированной С++ компилятором из Вижуал студии 2008. Есть подозрение, что Майкрософтовский компилятор генерирует простой и, при этом, короткий код, который помещается в некие внутренние структуры процессора. Компилятор Интел С++ пытается оптимизировать, раздувая код, который перестает помещаться в эти структуры. Но это только мое предположение.
Здравствуйте, Ka3a4oK, Вы писали:
KK>3. Попробовал скомпилировать компилятором Интел C++. Скорость работы упала(!sic) на 30%(!sic) по сравнению с программой откомпилированной С++ компилятором из Вижуал студии 2008.
Очень странно. В моей практике как правило всё наоборот.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Ka3a4oK, Вы писали:
KK>Недавно писал одну небольшую утилиту для обработки неких данных. Программа преобразует один входной бинарный поток в другой бинарный поток, попутно проводя некие вычисления над потоком(подсчет CRC). Старался добиться максимальной скорости. Скорость я считал только для внутреннего цикла, который и выполнял всю основную работу, т.е. не учитывал ввода-вывода при подсчете скорости.
KK>Несколько наблюдений:
KK>1. Подход: "сделать все на адских C++ шаблонах — компилятор потом оптимизирует" не работает, если нужно добиться максимальной скорости. Переписал на макросах — заработало заметно быстрее. Одна функция заработала быстрее на 50%.
Profile-guided optimization применялась ?
С ее помощью можно очень хороших результатов добиваться, проверено.
KK>2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
Потому что деструкторы объектов должны вызываться при разматывании стека.
Эти механизмы задействуются каждый раз при входе в очередную область видимости (функция или блок),
отсюда и потери.
KK>3. Попробовал скомпилировать компилятором Интел C++. Скорость работы упала(!sic) на 30%(!sic) по сравнению с программой откомпилированной С++ компилятором из Вижуал студии 2008. Есть подозрение, что Майкрософтовский компилятор генерирует простой и, при этом, короткий код, который помещается в некие внутренние структуры процессора. Компилятор Интел С++ пытается оптимизировать, раздувая код, который перестает помещаться в эти структуры. Но это только мое предположение.
Я тоже сталкивался с некоторыми "странностями" интеловского компилятора и в конце концов пришел к
выводу, что он может генерировать очень хороший код только под определенный процессор или семейство
процессоров и только если использовать развертывание циклов, SSE всех поколений и прочие трюки,
которых у этого инструмента в самом деле немеренное количество.
А в остальном по скорости он мало отличается от Вижуаловского.
Здравствуйте, okman, Вы писали:
O>Profile-guided optimization применялась ? O>С ее помощью можно очень хороших результатов добиваться, проверено.
Тут есть оборотная сторона — код искажается настолько, что анализироват crash dumps impossible. Кашеобразный код и понять почему упало уже не выходит. Это как применить omit stack pointer, от котрого сам MS отказался.
Грош цена вашим наблюдениям. Сначала посмотрите дизасм и выясните почему сгенерировался именно такой код, а потом пишите сюда свои наблюдения.
KK>некие внутренние структуры процессора
без комментариев %)
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, Ka3a4oK, Вы писали:
A>[...]
A>Грош цена вашим наблюдениям. Сначала посмотрите дизасм и выясните почему сгенерировался именно такой код, а потом пишите сюда свои наблюдения.
Смотрел. Вижуал сишный код — простой как доска. Интеловский — сложный.
KK>>некие внутренние структуры процессора A>без комментариев %)
Что вас развеселило?
O>Я тоже сталкивался с некоторыми "странностями" интеловского компилятора и в конце концов пришел к O>выводу, что он может генерировать очень хороший код только под определенный процессор или семейство O>процессоров и только если использовать развертывание циклов, SSE всех поколений и прочие трюки, O>которых у этого инструмента в самом деле немеренное количество. O>А в остальном по скорости он мало отличается от Вижуаловского.
Я тоже сначала пытался развернуть цикл, но "свернутый" цикл работает быстрее.
KK>>2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
O>Потому что деструкторы объектов должны вызываться при разматывании стека. O>Эти механизмы задействуются каждый раз при входе в очередную область видимости (функция или блок), O>отсюда и потери.
Код примерно такой:
main
{
try
{
код
код
код
засекаем время
цикл()
{
код внутри цикла
}
замеряем время
код
код
код
}
catch()
{
}
}
При этом внутри цикла никакие сложные объекты не создаются и не уничтожаются. Вообще никакие объекты не создаются.
Здравствуйте, Ka3a4oK, Вы писали:
KK>2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
Интересно — x86 или x64? Или и там и там одинаковый эффект?
По поводу Интел C++. Скачал недавно их разрекламированую "ipp+composer+compiler+примеры" (библиотека супер отпитимизированых примитив с компиляором, профайлером и примерами) решил проверить насколько быстр и оптимизирован интел++ (меня интересовали только видео кодеки) В общем скомпилировал версию интеловским компилятором и версию VC, всё с всеми включеными оптимизациями. Разница скрости декодирования(h264) видна была невооруженм зглядом (в пользу VC++2008) замерив тики получил что код скомпилированый VC++ работает на 30% быстрее. Правда эксперемент полючился грязноватый, так как сами примитивы лежали в lib (т.е я протестировал весь код кроме самих примитив) и проц у меня AMD, но всё равно — факт налицо, 'cl.exe' крут.
Здравствуйте, butcha, Вы писали:
B>проц у меня AMD
ключевой момент %) мало ли того, что оптимизации расчитвны под интел, так еще и под амд оптимизарот нарочно работает хуже
Здравствуйте, о_О, Вы писали:
B>>проц у меня AMD о_О>ключевой момент %) мало ли того, что оптимизации расчитвны под интел,
Intel компилер заточен оптимизировать с учётом глубоких знаний сильных мест архитектуры Intel процов. Странно правда?
о_О>так еще и под амд оптимизарот нарочно работает хуже
Это ты желтизны начитался.
Если у тебя скомпилен код с выбором альтернативных веток для разных процов то для определённых семейств Intel процов будут определённые ветки исполнения с оптимизациями под эти процы а для всех остальных — generic ветка.
В доках чётко написано:
/Qax
Tells the compiler to generate multiple, processor-specific auto-dispatch code paths for Intel processors if there is a performance benefit.
Я собираю свои проги с /Qx ключом, который генерит только оптимизированную ветку, без generic path.
И эти проги работают на AMD процах. По крайней мере за долгое время ни пришло ни одного бага на эту тему.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, butcha, Вы писали:
B>По поводу Интел C++. Скачал недавно их разрекламированую "ipp+composer+compiler+примеры" (библиотека супер отпитимизированых примитив с компиляором, профайлером и примерами) решил проверить насколько быстр и оптимизирован интел++ (меня интересовали только видео кодеки) В общем скомпилировал версию интеловским компилятором и версию VC, всё с всеми включеными оптимизациями. Разница скрости декодирования(h264) видна была невооруженм зглядом (в пользу VC++2008) замерив тики получил что код скомпилированый VC++ работает на 30% быстрее. Правда эксперемент полючился грязноватый, так как сами примитивы лежали в lib (т.е я протестировал весь код кроме самих примитив) и проц у меня AMD, но всё равно — факт налицо, 'cl.exe' крут.
Как я могу reproduce описанный эффект?
У меня тесты либы с криптографическими примитивами до перехода её на C++0x рвали cl 2008 где то 20%-50%. После перехода 2008я её просто не в состоянии собрать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, okman, Вы писали:
KK>>2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
O>Потому что деструкторы объектов должны вызываться при разматывании стека. O>Эти механизмы задействуются каждый раз при входе в очередную область видимости (функция или блок), O>отсюда и потери.
Какие еще деструкторы??? А без try они не вызываются чтоли?
Сказал же автор: нет исключений (не генерирует он их), меняется только факт наличия или отсутствия try-catch конструкции. Код нужно смотреть нагенерированный.
Аль профайлером померять два варианта программы и сравнить их (AQtime умеет).
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, butcha, Вы писали:
B>>По поводу Интел C++. Скачал недавно их разрекламированую "ipp+composer+compiler+примеры" (библиотека супер отпитимизированых примитив с компиляором, профайлером и примерами) решил проверить насколько быстр и оптимизирован интел++ (меня интересовали только видео кодеки) В общем скомпилировал версию интеловским компилятором и версию VC, всё с всеми включеными оптимизациями. Разница скрости декодирования(h264) видна была невооруженм зглядом (в пользу VC++2008) замерив тики получил что код скомпилированый VC++ работает на 30% быстрее. Правда эксперемент полючился грязноватый, так как сами примитивы лежали в lib (т.е я протестировал весь код кроме самих примитив) и проц у меня AMD, но всё равно — факт налицо, 'cl.exe' крут.
CC>Как я могу reproduce описанный эффект? CC>У меня тесты либы с криптографическими примитивами до перехода её на C++0x рвали cl 2008 где то 20%-50%. После перехода 2008я её просто не в состоянии собрать.
Блин, я уже снёс "composer", он был демо на 1 месяц, в общем "ipp+composer+compiler" идут в одном бандле, примеры надо скачивать отдельно, там же на странице даунлоадс файл "w_ipp-samples_p_7.0.2.048.zip" в примерах есть проекты под VC2008 и VC2010 (там есть готовые аудио-видео-имидж-спич- кодеки, чтото для работы со строками, компрессия и т.п.). После установки композера в студии появляется тулбар интела с возможности переключения текущего компилятора между интел-VC. С компилированием интелом++ у меня тоже были грабли — надо ручками создать глобальную переменную IPPROOT с путем к корневой папке где установилась ipp, далее она по умолчанию настроена на динамическую линковку, чтоб перейти на статическую надо в каком то конфиг-файле (он лежит в папке с инклюдами) обьявить это явно. Почитайте файл INSTALL идущий с "ipp" там довольно подробно описана инсталяция, я просто уже не помню подробностей. В примерах я компилировал "simple_player" — это приложение командной строки — видеоплеер, построено на либе типа DirectShow's BaseClasses (кстати интересная либа, правда густо перемешана всяким трассировочно-перфомансно-измерительным кодом) я не стал вникать в интеловкский профайлер, вставил пару "__rdtsc()" в какой то из xxxDecoderFrame() и тупо трассировал тики в файл (самописным нетормозным трассером) Вот и всё. Чтоб скачать всё это добро надо зарегиться у интелов на сайте, согласиться, что вы не выдадите бен-ладену коммерческую тайну, и качайте. Бандл с composer'ом назывется "composer_2011_setup.exe" (там лежит компилятор, аддоны к студии, либа ipp, профайлер, они — демо на месяц, естесно без исходников) Примеры вроде без ограничений. Есть подобные примитивы у AMD — FRAMEWAVE но ими я ещё не занимался.
Здравствуйте, trophim, Вы писали:
T>Здравствуйте, okman, Вы писали:
KK>>>2. Просто добавление обрамляющего блок try catch в функцию main привел к снижению скорости обработки на 10%. При этом не было выкинуто или обработано хоть одно исключение.
O>>Потому что деструкторы объектов должны вызываться при разматывании стека. O>>Эти механизмы задействуются каждый раз при входе в очередную область видимости (функция или блок), O>>отсюда и потери.
T>Какие еще деструкторы??? А без try они не вызываются чтоли? T>Сказал же автор: нет исключений (не генерирует он их), меняется только факт наличия или отсутствия try-catch конструкции. Код нужно смотреть нагенерированный.
А что Вас так удивило ?
У меня в одной программе наблюдалось в точности такое же поведение — проседание производительности
при добавления внешнего try/catch, причем исключения тоже нигде не выбрасывались и не обрабатывались.
Сгенерированный ассемблерный код был совершенно идентичным, а различия оказались в одной из
функций STL, связанной с std::cout (использовался вывод на консоль), которую компилятор почему-то
по-разному оптимизировал, в зависимости от наличия или отсутствия того самого блока try/catch.
Здравствуйте, okman, Вы писали:
T>>Какие еще деструкторы??? А без try они не вызываются чтоли? T>>Сказал же автор: нет исключений (не генерирует он их), меняется только факт наличия или отсутствия try-catch конструкции. Код нужно смотреть нагенерированный.
O>А что Вас так удивило ? O>У меня в одной программе наблюдалось в точности такое же поведение — проседание производительности O>при добавления внешнего try/catch, причем исключения тоже нигде не выбрасывались и не обрабатывались. O>Сгенерированный ассемблерный код был совершенно идентичным, а различия оказались в одной из O>функций STL, связанной с std::cout (использовался вывод на консоль), которую компилятор почему-то O>по-разному оптимизировал, в зависимости от наличия или отсутствия того самого блока try/catch.
OMG. Неисповедимы пути исключений... Буду знать.
Надо полагать это особенность (недо)оптимизатора такая?
GCC таким болеет, интересно.
On 15.04.2011 20:39, Ka3a4oK wrote:
> 1. Подход: "сделать все на адских C++ шаблонах — компилятор потом оптимизирует" > не работает, если нужно добиться максимальной скорости. Переписал на макросах — > заработало заметно быстрее. Одна функция заработала быстрее на 50%.
НЕ ВЕРЮ ((С) Станиславский).
> 2. Просто добавление обрамляющего блок try catch в функцию main привел к > снижению скорости обработки на 10%. При этом не было выкинуто или обработано > хоть одно исключение.
Это общеизвестный факт. Верю.
> 3. Попробовал скомпилировать компилятором Интел C++. Скорость работы упала(!sic) > на 30%(!sic) по сравнению с программой откомпилированной С++ компилятором из > Вижуал студии 2008.
Это ты его не настроил (оптимизацию не настроил).
Есть разные цели оптимизации, ты видимо этим не озадачивался, врубил дефолтную.
MZ>Это ты его не настроил (оптимизацию не настроил). MZ>Есть разные цели оптимизации, ты видимо этим не озадачивался, врубил дефолтную.
Ну что значит не настроил? Во-первых, я настроил VS-компилятор, поигравшись настрйоками проекта.
При переключении проекта для компиляции Интел-компиялтором, подхватываются настройки от VS-проекта.
Если с этими настройками Интел-компилятор генерирует заметно более медленный код — это уже однозначно
фэйл. Во-вторых я немного поигрался настройками Интел-компилятора, мне так и не удалось научить его
умум разуму. М.б. мало игрался. Разгадка проста — VS-компилятор генерирует 60 ассемблерных инструкуций
для самого внутреннего цикла, а Интел — 90.