Я в шоке. Сравнение компиляторов VC++ и gcc
вообще, чего прога делает хоть бы запостил кусок, который медленно работает
Exception’ы там отсутствуют как класс =)
imho в счетных прогах размером 400 kb как правило есть один цикл размером 4 kb который жрет 99% времени. или в данном случае не так?
Из ключей используется –O3.
Но мой вопрос также подразумевает, какими ключами это можно исправить, если дело в них?
Если все таки приспичило gcc, то в начале важный вопрос. Алгоритм итерационный?
Программа какого рода? В целочисленной арифметике все существующие компиляторы примерно одинаковы. Но вот с плавающей точкой - тут действительно труба.
Алгоритм не итерационный. Однако его итерационность не может иметь отношения к делу. Рекурсивные вызовы тоже не по существу, их почти нет.
А что там с плавающей точкой?
Я в C++ не понимаю, но слышал, что некоторым помогает -fno-rtti -fno-exceptions.
труба
спс, попробую позже, сейчас возможности нет
еще интересно было бы сравнить с версиями посовременней
Еще можно попробовать -march=<тип_процессора> -finline-limit=<числа от 700 до 2000>
слышал, что для вычислительных задач 2.95 работает быстрее, чем 3.X
правда с поддержкой плюсов у него похуже будет, поэтому может не получиться
вобщем, попробуй привязать к конкретному процессору и использовать какие-нибудь sse там или что у тебя есть (3dnow? или что в AMD с вещественными числами работает?)
man gcc
и там искать
-march=
-mfpmath=
просто 7.х быстрее чем 6.0
компилятор | время выполнения (сек)
|
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 с этим делом обстоит...
Стоит заюзать профилировщик
Второй вариант работает в 5 раз ! медленнее. Я в недоумении, т.к. такого не может быть.Может быть, но конечно не в пять раз, но всё равно gcc медленнее
На rsdn.ru вроде была как-то статья про сравнение компиляторов. Так вот там по скорости математики вроде как раз рулили borland и microsoft, а gcc рулил только в плане loop-unrolling
Я вот еще о чем подумал.
Готовая программа использует cygwin1.dll и без нее не работает на сторонней машине.
Может дело в том, что она постоянно выдергивает из нее вызовы и потому так тормозит?
Можно ли как-то ее еще и слинковать с этой dll?
Ты думаешь что это будет сильно быстрее? Ведь вызовы функций (даже из статически слинкованной библиотеки) никуда не денутся. Или я ошибаюсь? cygwin1.dll вроде обеспечивает только реализацию unix-специфичных функций (вроде работы с файлами) под виндой. Может, возможно как-нибудь уменьшить их использование?
(например загрузочный live-cd с FreeBSD заюзать для этой цели)
как вариант заставить тот самый цикл выполняться десять раз подряд (без выполнения всего остального хотя, это хуже, конечно...
попробуй с этим: 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 мощно юзает всякие математические функции.
Нет, это просто closed source программа с бинарником только под Linux.
Если даже и документировано, что с того? Думаешь автор треда прочитал эту документацию? Я просто говорю, что есть такая неочевидная тонкость при измерении скорости работы программ. А ты не знаю чего сказать хочешь, скорее всего ничего.
2. Почитать http://gcc.gnu.org/ml/gcc-help/2003-01/msg00024.html
3. Что касается SSE, в последние пару месяцев поддержку SSE активно улучшали, если не в лом, хорошо бы попробовать собрать последний снапшот gcc-4.0.0.
что узкие места здесь другие, нежели в исходной программе (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?
Зря ты ветку не дочитал. Там дальше помнится было объяснение почему это плохой тест. Кратко: цикл можно соптимизировать в ничто.
Кроме того, проводите тестирование на Вашей программе, а не на искусственном примере. Или хотя бы, как предлагается дальше по ссылке, используйте val1, val2, val3 и складывайте их в конце цикла.
Можно еще попробовать -funroll-all-loops (вроде должно работать с -O3 а также более агрессивный инлайнинг, это регулируется через механизм параметров (--param <name>=<value>).
И все же, попробуйте 4.0.0 пререлиз. Я не знаю, где его можно взять собранный, но самому собрать несложно, на современном P4 должно быть около получаса.
Да, зря (дочитал, но забил ). На правильном примере отношение скоростей стало 1.25, по-прежнему, в пользу Visual C. А release работает быстрее чем debug.
-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 с оптимизацией рулит.
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 с оптимизацией рулит.
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 примерно одинакова... т.е. разговоры о том, что под линуксом расчетные программы быстрее не оправдались...
вывод: - 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-версию работать с примерно такой же скоростью. В чем здесь может быть дело?