Я в шоке. Сравнение компиляторов VC++ и gcc
exception-ы используются? они под cygwin сильно медленные
вообще, чего прога делает хоть бы запостил кусок, который медленно работает
вообще, чего прога делает хоть бы запостил кусок, который медленно работает
Запостить не могу. Там 400Kb.
Exception’ы там отсутствуют как класс =)
Exception’ы там отсутствуют как класс =)
Наверное очень глупый вопрос, но на всякий случай спрошу: какие ключи компилятора используются (у gcc) ?
imho в счетных прогах размером 400 kb как правило есть один цикл размером 4 kb который жрет 99% времени. или в данном случае не так?
imho в счетных прогах размером 400 kb как правило есть один цикл размером 4 kb который жрет 99% времени. или в данном случае не так?
Цикл такой безусловно есть. Только вызовы, которые из него делаются как раз и составляют в целом почти все 400K
Из ключей используется –O3.
Но мой вопрос также подразумевает, какими ключами это можно исправить, если дело в них?
Из ключей используется –O3.
Но мой вопрос также подразумевает, какими ключами это можно исправить, если дело в них?
Не парься и возьми icc. gcc - действительно плохой компилятор. Он такой популярный, потому что он бесплатный и поддержано много платформ, а вовсе не потому, что он хорошо компилирует.
Если все таки приспичило gcc, то в начале важный вопрос. Алгоритм итерационный?
Если все таки приспичило gcc, то в начале важный вопрос. Алгоритм итерационный?
Программа какого рода? В целочисленной арифметике все существующие компиляторы примерно одинаковы. Но вот с плавающей точкой - тут действительно труба.
Спасибо за совет про icc, но должен использоваться именно gcc и среда cygwin.
Алгоритм не итерационный. Однако его итерационность не может иметь отношения к делу. Рекурсивные вызовы тоже не по существу, их почти нет.
Алгоритм не итерационный. Однако его итерационность не может иметь отношения к делу. Рекурсивные вызовы тоже не по существу, их почти нет.
А что там с плавающей точкой?
Я в C++ не понимаю, но слышал, что некоторым помогает -fno-rtti -fno-exceptions.
труба
про трубу не слышал
спс, попробую позже, сейчас возможности нет
спс, попробую позже, сейчас возможности нет
еще интересно было бы сравнить с версиями посовременней
Еще можно попробовать -march=<тип_процессора> -finline-limit=<числа от 700 до 2000>
или подревнее
слышал, что для вычислительных задач 2.95 работает быстрее, чем 3.X
правда с поддержкой плюсов у него похуже будет, поэтому может не получиться
слышал, что для вычислительных задач 2.95 работает быстрее, чем 3.X
правда с поддержкой плюсов у него похуже будет, поэтому может не получиться
Еб! такой трактат написал и не закомитил
вобщем, попробуй привязать к конкретному процессору и использовать какие-нибудь sse там или что у тебя есть (3dnow? или что в AMD с вещественными числами работает?)
man gcc
и там искать
-march=
-mfpmath=
вобщем, попробуй привязать к конкретному процессору и использовать какие-нибудь sse там или что у тебя есть (3dnow? или что в AMD с вещественными числами работает?)
man gcc
и там искать
-march=
-mfpmath=
просто 7.х быстрее чем 6.0
Результаты тестирования такие
Должен сказать еще, что оптимизация под конкретный процессор бесперспективна вот почему.
1. Программа будет собираться на одной машине, а запускаться на многих, заведомо неизвестно каких.
2. И главное, vc-версия, которую я использовал в этом тесте была собрана на другой машине, так что она явно не оптимизирована под этот проц.
компилятор | время выполнения (сек)
|
VC | 10
gcc | 69
gcc -O3 | 50
gcc -O3 -fno-rtti -fno-exceptions | 35
gcc -O3 -march=pentium4 | 51
Должен сказать еще, что оптимизация под конкретный процессор бесперспективна вот почему.
1. Программа будет собираться на одной машине, а запускаться на многих, заведомо неизвестно каких.
2. И главное, vc-версия, которую я использовал в этом тесте была собрана на другой машине, так что она явно не оптимизирована под этот проц.
А стандартная библиотека активно используется?
Например, динамическое выделение памяти, в том числе operator new, в том числе неявный?
Кто знает, как в cygwin с этим делом обстоит...
Например, динамическое выделение памяти, в том числе operator new, в том числе неявный?
Кто знает, как в cygwin с этим делом обстоит...
Стоит заюзать профилировщик
Второй вариант работает в 5 раз ! медленнее. Я в недоумении, т.к. такого не может быть.Может быть, но конечно не в пять раз, но всё равно gcc медленнее

На rsdn.ru вроде была как-то статья про сравнение компиляторов. Так вот там по скорости математики вроде как раз рулили borland и microsoft, а gcc рулил только в плане loop-unrolling

Я точно не знаю. Хотя в выделении памяти тоже может быть дело.
Я вот еще о чем подумал.
Готовая программа использует cygwin1.dll и без нее не работает на сторонней машине.
Может дело в том, что она постоянно выдергивает из нее вызовы и потому так тормозит?
Можно ли как-то ее еще и слинковать с этой dll?
Я вот еще о чем подумал.
Готовая программа использует cygwin1.dll и без нее не работает на сторонней машине.
Может дело в том, что она постоянно выдергивает из нее вызовы и потому так тормозит?
Можно ли как-то ее еще и слинковать с этой dll?
Ты думаешь что это будет сильно быстрее? Ведь вызовы функций (даже из статически слинкованной библиотеки) никуда не денутся. Или я ошибаюсь? cygwin1.dll вроде обеспечивает только реализацию unix-специфичных функций (вроде работы с файлами) под виндой. Может, возможно как-нибудь уменьшить их использование?
А что будет, если собрать под каким-нть линухом/БСД на той же машине этот же проект?
(например загрузочный live-cd с FreeBSD заюзать для этой цели)
как вариант заставить тот самый цикл выполняться десять раз подряд (без выполнения всего остального хотя, это хуже, конечно...
(например загрузочный live-cd с FreeBSD заюзать для этой цели)
как вариант заставить тот самый цикл выполняться десять раз подряд (без выполнения всего остального хотя, это хуже, конечно...
не правильно сравнение если gcc используется cygwinновский, то проги, написанные под MS VS 6.0 надо было запускать под wine
попробуй с этим: http://www.mingw.org/download.shtml
есть еще старые порты: emx(os/2) и rsx.
если интересно, то какие-то версии rar использовали последнюю библиотеку и никто не жаловался на производительность.
З.Ы. другие люди умеют писать производительные приложения, используя код gcc в качестве компилятора, значит нет достаточной подготовки, если не получается. под msvs 6.0, если бы ты последовал рекомендациям и сделал mfc приложение оно бы особо маленьким не было.
З.З.Ы. зря используешь msvs 6.0: intel C compiler и компилятор unmanaged С++ из MSVS .NET 2003 ощутимо быстрее
попробуй с этим: http://www.mingw.org/download.shtml
есть еще старые порты: emx(os/2) и rsx.
если интересно, то какие-то версии rar использовали последнюю библиотеку и никто не жаловался на производительность.
З.Ы. другие люди умеют писать производительные приложения, используя код gcc в качестве компилятора, значит нет достаточной подготовки, если не получается. под msvs 6.0, если бы ты последовал рекомендациям и сделал mfc приложение оно бы особо маленьким не было.
З.З.Ы. зря используешь msvs 6.0: intel C compiler и компилятор unmanaged С++ из MSVS .NET 2003 ощутимо быстрее
Сам не профессиональный программер, но по собственному опыту могу сказать следующее: расчетная Прога с кучей операций файлового ввода-вывода и с кучей операций с плавающей точкой (среднее время выполнения - 1-2 суток) скомпиленная gcc под Линух в режиме эмуляции Линуха под Фрей работает почти в 2(ДВА!) раза быстрее, чем ее цыгвиновский аналог, скомпилированный той же версией gcc.
скомпиленная gcc под Линух в режиме эмуляции Линуха под ФрейОдно слово - юнексоиды...
Не, это скорее специфика FreeBSD 

под конкретный процессор бесперспективнаЕсть такая штука - Blend. Это когда компилятор генерирует варианты для нескольких процессоров, а в самом начале программы стоит cpuid и развилка. Так что и 1. и 2. ничего не значат...
PS. А еще пустись не под cygwin-ом, чтобы за зря gcc не ругать

Однако его итерационность не может иметь отношения к делу.Я потому спросил, что мы на работе на такой прикол наткнулись. Разные компиляторы по разному следят за точностью вещественных вычислений, и поэтому зачастую программам скомпилированным разными компиляторами или с разными опциями требуется разное количество итераций для достижения заданной точности результата. Отсюда и разница времени исполнения. Ты уверен, что в твоей программе такого быть не может?
Разные компиляторы по разному следят за точностью вещественных вычисленийОднако, обычно, это "по-разному" документировано и управляется. Как минимум, у IСС/IFC и GCC.
А не использует ли твоя программа например libm? Может быть большая часть процессорного времени проводится не в твоём кода, а библиотеках.
Сам не профессиональный программер, но по собственному опыту могу сказать следующее: расчетная Прога с кучей операций файлового ввода-вывода и с кучей операций с плавающей точкой (среднее время выполнения - 1-2 суток) скомпиленная gcc под Линух в режиме эмуляции Линуха под Фрей работает почти в 2(ДВА!) раза быстрее, чем ее цыгвиновский аналог, скомпилированный той же версией gcc.Наверное речь про dft или taina?

Пока самым приемлемым объяснением описанного тобою факта считается, что libm в FreeBSD побыстрее libm в Linux. А dft мощно юзает всякие математические функции.
> Не, это скорее специфика FreeBSD
Нет, это просто closed source программа с бинарником только под Linux.
Нет, это просто closed source программа с бинарником только под Linux.
Ну вот ты говоришь компилятору - распараллеливай вещественную арифметику на SSE. Ну он что-то смог на SSE положить, что-то на сопроцессоре оставил из каких-то своих соображений. На сопроцессоре регистры 80 битные, а на SSE 64 битные. Соответственно, при вычислении на SSE точность ниже, чем на сопроцессоре. Ну и что тут может быть задокументировано? Ты предлагаешь, чтобы компилятор про каждое умножение в программе сказал, где он его решил выполнить? И то не поможет...
Если даже и документировано, что с того? Думаешь автор треда прочитал эту документацию? Я просто говорю, что есть такая неочевидная тонкость при измерении скорости работы программ. А ты не знаю чего сказать хочешь, скорее всего ничего.
Если даже и документировано, что с того? Думаешь автор треда прочитал эту документацию? Я просто говорю, что есть такая неочевидная тонкость при измерении скорости работы программ. А ты не знаю чего сказать хочешь, скорее всего ничего.
1. Попробовать -mno-cygwin
2. Почитать http://gcc.gnu.org/ml/gcc-help/2003-01/msg00024.html
3. Что касается SSE, в последние пару месяцев поддержку SSE активно улучшали, если не в лом, хорошо бы попробовать собрать последний снапшот gcc-4.0.0.
2. Почитать http://gcc.gnu.org/ml/gcc-help/2003-01/msg00024.html
3. Что касается SSE, в последние пару месяцев поддержку SSE активно улучшали, если не в лом, хорошо бы попробовать собрать последний снапшот gcc-4.0.0.
На простейшем примере результаты такие, что показывает,
что узкие места здесь другие, нежели в исходной программе (400K
о которой речь шла выше.
Мораль: наилучшую скорость дает
Ключ -mno-cygwin является вредоносным.
Тестовая программа взята с ресурса
http://gcc.gnu.org/ml/gcc-help/2003-01/msg00024.html
что узкие места здесь другие, нежели в исходной программе (400K
о которой речь шла выше.
Visual C++6.0
gcc-3.3.1 (cygwin)
compiler | time (sec)
|
VC (release) | 6.529
VC (debug) | 1.221
gcc | 2.914
gcc -O3 -ffast-math | 1.852
gcc -O3 -ffast-math -malign-double | 1.852
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions | 1.842
gcc -mno-cygwin | 7.281
gcc -O3 -ffast-math -mno-cygwin | 6.529
Мораль: наилучшую скорость дает
При этом отношение скоростей составляет 1.5 в пользу Visual C.
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions | 1.842
Ключ -mno-cygwin является вредоносным.
Тестовая программа взята с ресурса
http://gcc.gnu.org/ml/gcc-help/2003-01/msg00024.html
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char* argv[])
{
clock_t start, finish;
start = clock;
printf("\nstart...\n");
for (double i = 0; i < 1e6; i++) {
double val = (double)i + 0.01;
val = log(val);
val = exp(val);
val = sin(val);
val = cos(val);
val = tan(val);
val = log10(val);
val = i;
val = sqrt(val);
val = pow(val, 4.567);
}
finish = clock;
double duration = (doublefinish - start) / CLOCKS_PER_SEC;
printf("Elapsed time = %g", duration);
return 0;
}
а почему VC release работает медленее чем VC debug?
Зря ты ветку не дочитал. Там дальше помнится было объяснение почему это плохой тест. Кратко: цикл можно соптимизировать в ничто. 

Нет желания все-таки попробовать задействовать настройку под процессор (-march, -mfpmath)? При использовании -mno-cygwin попробовать -mhard-float. Убедитесь хотя бы, что плавающая точка выполняется на железе.
Кроме того, проводите тестирование на Вашей программе, а не на искусственном примере. Или хотя бы, как предлагается дальше по ссылке, используйте val1, val2, val3 и складывайте их в конце цикла.
Можно еще попробовать -funroll-all-loops (вроде должно работать с -O3 а также более агрессивный инлайнинг, это регулируется через механизм параметров (--param <name>=<value>).
И все же, попробуйте 4.0.0 пререлиз. Я не знаю, где его можно взять собранный, но самому собрать несложно, на современном P4 должно быть около получаса.
Кроме того, проводите тестирование на Вашей программе, а не на искусственном примере. Или хотя бы, как предлагается дальше по ссылке, используйте val1, val2, val3 и складывайте их в конце цикла.
Можно еще попробовать -funroll-all-loops (вроде должно работать с -O3 а также более агрессивный инлайнинг, это регулируется через механизм параметров (--param <name>=<value>).
И все же, попробуйте 4.0.0 пререлиз. Я не знаю, где его можно взять собранный, но самому собрать несложно, на современном P4 должно быть около получаса.
Да, зря (дочитал, но забил
). На правильном примере отношение скоростей стало 1.25, по-прежнему, в пользу Visual C. А release работает быстрее чем debug.
). На правильном примере отношение скоростей стало 1.25, по-прежнему, в пользу Visual C. А release работает быстрее чем debug.Я уже писал, что –march использовался, влияния не оказывает.
-funroll-all-loops также не влияет.
Пробовать 4.0.0 пока не буду, у меня другие задачи
-funroll-all-loops также не влияет.
Пробовать 4.0.0 пока не буду, у меня другие задачи

мои результаты:
icl /G6 0.33 s
icl /G6 /QaxK /QxK 0.32
icl /G6 /QaxK /QxK /Qip 0.26
vc 6.0 debug 0.992 s
vc 6.0 release 0.045 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -m3dnow 1.399
gcc -msse 2.23
[gcc 3.3.1-2]
[icl 7.1]
вывод: - icl с оптимизацией рулит.
icl /G6 0.33 s
icl /G6 /QaxK /QxK 0.32
icl /G6 /QaxK /QxK /Qip 0.26
vc 6.0 debug 0.992 s
vc 6.0 release 0.045 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -m3dnow 1.399
gcc -msse 2.23
[gcc 3.3.1-2]
[icl 7.1]
вывод: - icl с оптимизацией рулит.
vc 6.0 release 0.045 s? может 0.45? а то получается быстрее всех

для полноты картины не хватает теста для VC++ 7.1
сорри
правильно так:
windows
icl /G6 0.033 s
icl /G6 /QaxK /QxK 0.032
icl /G6 /QaxK /QxK /Qip 0.026
vc 6.0 debug 0.992 s
vc 6.0 release 0.045 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -m3dnow 1.399
gcc -msse 2.23
[gcc cygwin 3.3.1-2]
[icl 7.1]
вывод: - icl с оптимизацией рулит.
правильно так:
windows
icl /G6 0.033 s
icl /G6 /QaxK /QxK 0.032
icl /G6 /QaxK /QxK /Qip 0.026
vc 6.0 debug 0.992 s
vc 6.0 release 0.045 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -m3dnow 1.399
gcc -msse 2.23
[gcc cygwin 3.3.1-2]
[icl 7.1]
вывод: - icl с оптимизацией рулит.
linux:
gcc [3.3.2]
gcc 1.09 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -msse 0.77 s
icc [7.0]
icc 0.01 s
gcc [3.3.2]
gcc 1.09 s
gcc -O3 -ffast-math -malign-double -fno-rtti -fno-exceptions -msse 0.77 s
icc [7.0]
icc 0.01 s
что=то я нафлудил цифрами
живой пример:
когда я спортировал расчетную программу GAMESS под ifc 7.0 под линукс, то скорость возрасла в 2=2.5 раза по сравнению с gcc 3.3.2
Причем, как оказалось, что скорость программы под виндовс и под линукс при одной и той же версии компиляторя ifc примерно одинакова... т.е. разговоры о том, что под линуксом расчетные программы быстрее не оправдались...
живой пример:
когда я спортировал расчетную программу GAMESS под ifc 7.0 под линукс, то скорость возрасла в 2=2.5 раза по сравнению с gcc 3.3.2
Причем, как оказалось, что скорость программы под виндовс и под линукс при одной и той же версии компиляторя ifc примерно одинакова... т.е. разговоры о том, что под линуксом расчетные программы быстрее не оправдались...
вывод: - icl с оптимизацией рулит.Быстро у тебя выводы получаются. Люди годами тестовые пакеты составляют, чтобы производительность процессоров/компиляторов исследовать. А ты написал какой-то пример непонятный - и готово, все узнал... Ты хоть результат его работы визуализировать умеешь, а то может в нем ошибка есть?
По меньшей мере нужны не отдельные цифры, а _график_, как время работы зависит от объема данных. Когда кеш заканчивается, картина как правило резко меняется, не каждый компилятор способен сгенерировать cache-friendly код. Уже не говоря о том, что надо хотя бы штук 5 различных программ тестовых, в которых локальность по данным разная, разный шаблон обращения к памяти, разное отношение целочисленной и вещественной арифметики и т. п.Быстро у тебя выводы получаются.Конечно, я не прав, что делаю столько категоричные выводы.
Но я приводил выше пример с GAMESS. Скорость работы с компиляцией ifl с заточкой под процессор и с IPO была быстрее, чем другие варианты (другие параметры ifl, другие компиляторы cvf или gcc/g77). Плюс по многим тестам, которые есть на iXBT, icl/ifl выигрывал у других компиляторов. Поэтому вообще-то я хотел сказать только одно: ксли есть возможность использовать интеловский компилятор и не хочется тратить время на изучение производительности процессор/компилятор, то в больше чем половине задач это будет оптимальный выбор.
Оставить комментарий
mama10001
Есть численная программа написанная на С++.Собираем с помощью Visual C++6.0
Собираем с помощью g++ 3.3.1 (cygwin версия)
Запускаем.
Сравниваем время работы.
Второй вариант работает в 5 раз ! медленнее. Я в недоумении, т.к. такого не может быть.
Вопрос. Как заставить gcc-версию работать с примерно такой же скоростью. В чем здесь может быть дело?