С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.97/256: Рейтинг темы: голосов - 256, средняя оценка - 4.97
tux21

Посоветуйте C/C++ компилятор под Linux

28.04.2008, 23:12. Показов 53729. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Интересует максимальная оптимизация по скорости. Какой выбрать? GCC/Intel/SUN/lcc?/etc? На liberatum.ru ничего не нашел.
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.04.2008, 23:12
Ответы с готовыми решениями:

подскажите, где можно скачать компилятор для C++ под Linux?
...можно скачать компилятор для C++ под Linux? заранее спасибо!

Посоветуйте что-то почитать по сокетам в C++ под linux.
Посоветуйте что-то почитать по сокетам в C++ под linux.

Компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7. Посоветуйте другой компилятор
Здравствуйте! Я недавно начал заниматься С++, но мой компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7 Посоветуйте какой...

31
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
18.04.2009, 18:31
Студворк — интернет-сервис помощи студентам
Пользователю всё равно, кто виноват в том, что у него что-то не компилируется. И если проблема в том, что сторонний компилятор не работает соотвествующим образом под линухом, хотя там можно доработать огромным напильником (и постоянно дорабатывать, например, при обновлении glibc, binutils или как-йото прикладной библиотеки) - пользователю такой компилятор не нужен
Да, поэтому пусть использует гсс, чтобы все компилилось. Я, как пользователь, говорю, что у меня компилится все. У кого не компилится - это его проблемы.
Я говорю не о том, возможно ли это теортетически при рассмотрении модели идеального компилятора в ваккуууме. А о том, что на ТЕКУЩИЙ момент на ТЕКУЩЕЙ версии gcc выжать производительность конкретно в том месте нельзя в силу технических особенностей ТЕКУЩЕГО устройства компилятора
Я не говорю о идельаном компиляторе. Я говорю о том, что гс может быть изменен, чтобы удовлетворить нужные потребности. Если это будет необходимо, конечно. даже в силу текущих его особенностей. Трудности могут быть, но они вполне преодолимы, имхо.
Если компилятор не понимает (в смысле не понимает её как входной язык) конструкцию языка, то компилятор однозначно на свалку. Если компилятор не понимает (в смысле "неправильно работает") то, что написано правильно - это плохой компилятор (к коим по большому счёту и относится gcc). В момент разработки программы ты можешь все эти "плохие" места обходить, пополняя собственные знания о том, где ждать от компилятора сюрпризов. Но когда программа уже написана и при переносе на другой компилятор (или другую версию этого же компилятора) у неё возникают проблемы - вот тут ты и помудохаешься с отладкой
From initial message я имел ввиду понимание особенностей конкретной архитектуры и умение оптимизировать для нее, а не конструкций языка. Что ты описал - с этим согласен.

гсс некоторые вещи можно простить ввиду поддержки в нем многоплатформенности. Когда какой-нибудь, VC++ изначально под вантуз и все в нем под это дело заточено, то gcc явно будет отставать в плане многих конструкций (и то не факт, что всех). Да и в некоторых случаях ненамного.
В моей практике мне приходилось сравнивать по скорости конструкции только gcc и intel compiler. Так вот, в некоторых случаях отставал и гсс, и интел компилер.
Ну и несколько взглядов мельком на сравнение компилеров показывало, что гсс совсем не на последнем месте.

Отсюда делаем вывод, что под линухом спокойно можно юзать gcc. И ничего страшного в этом нет.

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

P. P. S. вот я уже много лет пользуюсь gcc(g++). Иногда Intel C++ Compiler. Скажи, с какими трудностями я должен был столкнуться при его использовании? Есть ли причина, не использовать его больше? Или ее нет?
(повторю, что прощаю гсс многое ввиду того, что он несет на себе большой груз кроссплатформенности. за все нужно платить )
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.04.2009, 18:55
Цитата Сообщение от Vourhey Посмотреть сообщение
Да, поэтому пусть использует гсс, чтобы все компилилось. Я, как пользователь, говорю, что у меня компилится все. У кого не компилится - это его проблемы.
То было сказано в контексте использования НЕ-gcc. И с этой точки зрения пользователь такой вариант забракует по указанным выше причинам. И дело может быть не столько в исходниках твоей программы, сколько в окружении, которое живёт по своим стандартам. К примеру, компиляция задач Си++ пролетает автоматом, потому что манглирование имён каждый компилятор делает по-своему, а на линухе все библиотеки, собраны понятно дело gcc'ями

Цитата Сообщение от Vourhey Посмотреть сообщение
Я не говорю о идельаном компиляторе. Я говорю о том, что гс может быть изменен, чтобы удовлетворить нужные потребности. Если это будет необходимо, конечно. даже в силу текущих его особенностей. Трудности могут быть, но они вполне преодолимы, имхо.
Если ставить вопрос об изменении исходников компилятора - несомненно. Многие так и делают. Sun Microsystems тоже в своё время этим занимались

Цитата Сообщение от Vourhey Посмотреть сообщение
гсс некоторые вещи можно простить ввиду поддержки в нем многоплатформенности. Когда какой-нибудь, VC++ изначально под вантуз и все в нем под это дело заточено, то gcc явно будет отставать в плане многих конструкций (и то не факт, что всех). Да и в некоторых случаях ненамного.
Собственно об этом я и говорил. Ценой за многоплатформенность служит качество кода.

Цитата Сообщение от Vourhey Посмотреть сообщение
В моей практике мне приходилось сравнивать по скорости конструкции только gcc и intel compiler. Так вот, в некоторых случаях отставал и гсс, и интел компилер.
Ну и несколько взглядов мельком на сравнение компилеров показывало, что гсс совсем не на последнем месте.
Интеловский компилятор, насколько я знаю, умеет генерить mmx/sse интрукции. Т.е. ты всякую муть типа дискретных косинусных преобразований можешь написать на языке, и из-под компилятора получить код с предельной производительностью. Наверняка для этого придётся использовать pragm'ы, но в любом случае код у тебя написан на языке, а с ним всегда работать проще, чем с кодом на ассемблере

Цитата Сообщение от Vourhey Посмотреть сообщение
Отсюда делаем вывод, что под линухом спокойно можно юзать gcc. И ничего страшного в этом нет.
Опять-таки, не можно, а нужно, ибо больше нечего

Цитата Сообщение от Vourhey Посмотреть сообщение
P. S. правда, его последние версии меня несколько разочаровали. Использую более старые.
Ну вот как закончат они с gcc-4, выпустят наконец стабильную версию - скорее всего получится конфетка. Потом несколько лет будут мурыжить gcc-5 и весь этот процесс повторится снова

Цитата Сообщение от Vourhey Посмотреть сообщение
P. P. S. вот я уже много лет пользуюсь gcc(g++). Иногда Intel C++ Compiler. Скажи, с какими трудностями я должен был столкнуться при его использовании? Есть ли причина, не использовать его больше? Или ее нет?
"При его использовании" - ты имеешь ввиду gcc? Сейчас попробую наваять исходник, где gcc накосячит

Добавлено через 11 минут 24 секунды
У меня дома только gcc-4.2
Известные мне косяки на ней что-то не проявляются. Попробую на работе с более ранними версиями
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
18.04.2009, 18:58
Опять-таки, не можно, а нужно, ибо больше нечего
Ну можно и так поставить Но, я не вижу в этом ничего плохо, так как, код сгенеренный гсс меня вполне во всем устраивает. Ну почти
Ну вот как закончат они с gcc-4, выпустят наконец стабильную версию - скорее всего получится конфетка. Потом несколько лет будут мурыжить gcc-5 и весь этот процесс повторится снова
так с любым компилятором.

Ошибки есть в любом компиляторе. В gcc они, тем более, виднее, он открытый, обо всех багах известно.
Интеловский компилятор, насколько я знаю, умеет генерить mmx/sse интрукции
гсс также поддерживает ммх инструкции.

И не забываем, что гсс направлен на многоплатформенность.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.04.2009, 19:11
Приведу немного другой пример. Правда он не очень хороший

C++
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
int
main (void)
{
  unsigned char c = 257;
 
  printf ("%d\n", c);
 
  return 0;
}
Скомпиляем и запустим такой тест

Code
1
2
3
4
$ gcc a.c && ./a.out 
a.c: In function 'main':
a.c:23: warning: large integer implicitly truncated to unsigned type
1
Результат логичный. 257 это есть 0x101, что после приведения к char'у оставит нам только единичку

Теперь сделаем константу 257 плавающей

C++
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
int
main (void)
{
  unsigned char c = 257.0;
 
  printf ("%d\n", c);
 
  return 0;
}
Code
1
2
3
4
$ gcc a.c && ./a.out 
a.c: In function 'main':
a.c:23: warning: overflow in implicit constant conversion
255
На вид результат несколько неожиданный. Однако если обратиться к стандарту, то там сказано, что в случае преобразования из плавающего в целое гарантируется преобразование только таких величин, которые укладываются в диапазон результирующего целого. Т.е. в данном случае число 257 выходит за границу диапазона unsigned char'а, а потому результат преобразования по стандарту неопределён.

Идём дальше, теперь константу предварительно загоним в глобалдьную переменную, чтобы в момент компиляции не было свёртки констант

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
float f = 257.0;
 
int
main (void)
{
  unsigned char c = f;
 
  printf ("%d\n", c);
 
  return 0;
}
Code
1
2
$ gcc a.c && ./a.out 
1
Видим, что результат другой. ФОрмально к компилятору прикопаться в данном случае нельзя. Он отработал чётко по стандарту, а там где результат неопределён - сам дурак. Однако большинство разработчиков стараются, чтобы вот такие вот места, обозначенные как unspecified behaviour в стандарте, тем не менее делать их более менее "стандартно" - т.е. так, как казалось бы ожидает программист. И уж тем более, чтобы это не завислео от того, произошла свёртка констант на этапе компиляции ли нет. Повторюсь, в данном случае нет ни одной причины назвать компилятор gcc плохим, однако такие ситуации очень сильно усложняют отладку. Аналогичная ситуация возникнет, когда допустим компилируем без опции оптимизаций, то получаем один результат, а с потимизациями другой (потому что что-то там свернулось, что-то спропагировалось и вот на этапе компиляции произошла какая-то свёртка констант)

Добавлено через 4 минуты 43 секунды
Цитата Сообщение от Vourhey Посмотреть сообщение
так как, код сгенеренный гсс меня вполне во всем устраивает. Ну почти
Ну вот об это "почти" мы очень конкретно спотыкались при переходе с gcc-2.95.3 на gcc-3.4.6 и при переходе с gcc-3.4.6 на gcc-4.<не помню точно>

Цитата Сообщение от Vourhey Посмотреть сообщение
так с любым компилятором.
Но вот коммерческие компиляторы сначала отладят, а потом выпускают. А с Gcc наоборот. Правда это уже выходит за рамки нашего разговора (да и остаётся на совести разработчиков gcc)

Цитата Сообщение от Vourhey Посмотреть сообщение
гсс также поддерживает ммх инструкции.
Через builtin'ы - по-любому
Способен ли он сам из кода на Си родить mmx - для меня большой вопрос. Хотя если это строить на распознавании некоторых шаблонов, то может быть и строит

Цитата Сообщение от Vourhey Посмотреть сообщение
И не забываем, что гсс направлен на многоплатформенность.
Вот я и говорю, что многоплатформенность лежит в основе большинства его (gcc) бед
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
18.04.2009, 19:22
Вот я и говорю, что многоплатформенность лежит в основе большинства его (gcc) бед
Тем не менее, он не хуже остальных компиляторов (по крайней мере, ты ни одного убедительного недостатка не привел) и достаточно хорошо сделан.
А глюки были, есть и будут во всех компилерах.
Кстати, пример который ты привел мне не показал ничего необычного или неправильного.
Через builtin'ы - по-любому
Допустим, что даже через них. И че? Ниче. Что ты хотел, когда в названии того же Intel Compiler есть имя Intel. Еще б он в своем сердце ммх не поддерживал. Не смеши мои тапки. ммх, ссе есть в гсс. Даже если их нет, то это все решается асмом.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.04.2009, 19:39
Цитата Сообщение от Vourhey Посмотреть сообщение
ты ни одного убедительного недостатка не привел
В пользу того, что gcc "плохой" у меня была только одна аргументация - неправильная генерация кода в некоторых случаях. В понедельник на работе поищу образцы косяков, если они сохранились.

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

По поводу "достаточно хорошо сделан" - это вопрос несколько субъективный. Исходники gcc я видел и в них ковырялся. Правда ещё во времена gcc-2.95. Принцип построения компилятора сделан безусловно на высшем уровне - часть их опыта я перенял себе. Что касается качества кода (имею ввиду код самогО компилятора) - всё-таки он хромает и очень сильно. Правда после структурных переделок в gcc-3 и gcc-4 там скорее всего стало всё гораздо лучше. Но опять-таки многоплатформенность как ни крути влечёт за собой кучу затычек в коде

Больше аргументации "против" компилятора gcc с моей стороны не было

Всё вышесказанное было мной заявлено именно с точки зрения программиста-разработчика по результату 9 лет работы с gcc

В широком смысле компилятор gcc конечно же "плохим" назвать нельзя. Хотя бы потому, что им собрано чёрт-те знает сколько всего и под практически все современные платформы. По этому вопросу мы с тобой также единодушны

Добавлено через 4 минуты 36 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
А глюки были, есть и будут во всех компилерах.
За многие годы работы с Sun'овским компилятором не натолкнулся ни на один глюк компилятора. По отзыву тех, кто работает с микрософтовским компилятором - то же самое (вот что-что, а компилятор у микрософта действительно хорошо написан)

Цитата Сообщение от Vourhey Посмотреть сообщение
Кстати, пример который ты привел мне не показал ничего необычного или неправильного.
Ну.. когда при преобразовании 257 к char'у получается 255 - для меня это несколько непонятно. Т.е. не читая стандарт мне бы такой результат был бы непонятен

Цитата Сообщение от Vourhey Посмотреть сообщение
Допустим, что даже через них. И че? Ниче. Что ты хотел, когда в названии того же Intel Compiler есть имя Intel. Еще б он в своем сердце ммх не поддерживал. Не смеши мои тапки. ммх, ссе есть в гсс. Даже если их нет, то это все решается асмом.
Давай всё-таки по второму кругу ходить не будем. Всё, что решается асмом давай будем считать, что выходит за рамки дискуссии. Потому как будем считать, что разработка кода на ассембелере - занятие в разы более трудоёмкое, чем компилятором на языке
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
18.04.2009, 19:48
В пользу того, что gcc "плохой" у меня была только одна аргументация - неправильная генерация кода в некоторых случаях.
Ну, повторю, что глюки есть везде, че ж теперь делать
Но ни разу не сталкивался с тем, чтобы у меня что-то не работало, или работало не так. Я с gcc дрова делаю и ниче. Работают, не слетают, ведут себя предсказуемо.
Пример приведенный тобой выше не ошибка. Если дурак сидит за редактором, то он убьет и Intel C++ compiler и любой другой. Абсолютно любой.
Поэтому, однозначно, для линукса gcc
Ну.. когда при преобразовании 257 к char'у получается 255 - для меня это несколько непонятно. Т.е. не читая стандарт мне бы такой результат был бы непонятен
Ну он же предупредил, что overflow
Не читая описание функции, я бы не знал, что printf сможет на терминал строку вывести )
Добавлено через 34 секунды
Давай всё-таки по второму кругу ходить не будем. Всё, что решается асмом давай будем считать, что выходит за рамки дискуссии. Потому как будем считать, что разработка кода на ассембелере - занятие в разы более трудоёмкое, чем компилятором на языке
Я по кругу не хожу. Все это решается, как асмом, так и без асма.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.04.2009, 20:13
Цитата Сообщение от Vourhey Посмотреть сообщение
Ну, повторю, что глюки есть везде, че ж теперь делать
Понятно, что везде. Но их меньше, чем у коммерческих. Чёрт, опять по кругу

Цитата Сообщение от Vourhey Посмотреть сообщение
Но ни разу не сталкивался с тем, чтобы у меня что-то не работало, или работало не так. Я с gcc дрова делаю и ниче. Работают, не слетают, ведут себя предсказуемо.
Ну драйвера как ни крути - вещь специфичная. Значит по специфике твоей задачи тебе не приходится сталкиваться с косяками.

Цитата Сообщение от Vourhey Посмотреть сообщение
Пример приведенный тобой выше не ошибка.
Ага, я так и писал. Пример был больше как пожелание того, что я джу от "хорошего" софта (в частности, от компилятора). А перед этим к концу предыдущего поста прилепилось, если вдруг не прочёл - на gcc-4.2 я не смог воспроизвести известный мне косяк, а потому решил это дело до появления на работе отложить

Цитата Сообщение от Vourhey Посмотреть сообщение
Если дурак сидит за редактором, то он убьет и Intel C++ compiler и любой другой. Абсолютно любой.
Без вопросов

Цитата Сообщение от Vourhey Посмотреть сообщение
Поэтому, однозначно, для линукса gcc
Дык мы это уже постановили и утвердили

Цитата Сообщение от Vourhey Посмотреть сообщение
Я по кругу и не хожу. Все это решается, как асмом, так и без асма.
Ну... скажем так, тема для отдельной дискуссии. Когда что-то решается ассемблером - это конечно хорошо. Особено учитывая то, что в gcc ассемблерные вставки наверное сделаны лучшим в мире образом. По крайней мере то, что я видел на других компиляторах, по удобству НА МОЙ ВЗГЛЯД не идёт ни в какое сравнение с изобретением gcc'шников. Но, как и полагается в бесплатном компиляторе, нормальной документации к этому нет, а потому без поллитры не разобрать. Но те, кто разобрался, те наверняка не жалеют. Мне их концепция нравится имено как инженерное решение (скажу даже больше - я этим решением восхищаюсь).

Там, где средства языка недоступны (ОС, драфверы, ещё что-то низкоуровневое), ассемблерные вставки безусловно необходимы. Но всё-таки вытягивать поизводительность за счёт ассемблерных вставок - занятие неблагодарное. По многим причинам: во первых надо найти места, где теряется производительность, во вторых, надо аккруатно решить, что будет написано на вставках, а что на языке, в-третьих место состыковки вставки и кода на языке в результате не всегда получается оптимальным, в четвёртых само это дело писать много времени может уйти, в-пятых нужно чётко себе представлять ABI данной архитектуры, чтобы не напортачить и не испортить регистры и т.д. А потому сейчас разработчики компиляторов стараются вытягивать максимум именно с языкового уровня, пусть даже и с pragma'ми. Ну, или как варинт, использование неких строительных кубиков, написанных на ассемблере или сделанных в виде builtin'ов, как в gcc.

Тут скорее из разряда "на вкус и цвет". Лично я считаю, что ассемблерных вставок по возможности надо избегать. Если падение производительности за счёт написания на языке терпит, то лучше писать на языке - так надёжнее и на душе спокойнее. Из разряда "ну и пусть пидо$ас, зато живой остался". Т.е. я считаю, что на первом месте безоговорочно должна быть надёжность, а производительность - вопрос второй. Естественно, бывают специфические случаи (типа обработки данных с локатора в режиме реального времени), где нужно выжимать 100% производительности машины. Но если случай не такой, то мне кажется, лучше сделать перекос в сторону надёжности
1
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
18.04.2009, 20:17
За многие годы работы с Sun'овским компилятором не натолкнулся ни на один глюк компилятора. По отзыву тех, кто работает с микрософтовским компилятором - то же самое (вот что-что, а компилятор у микрософта действительно хорошо написан)
А я, например, сталкивался с глюками в VC++ при обработке некоторых валидных ассемблерных конструкций.
Лично я считаю, что ассемблерных вставок по возможности надо избегать
Да, это так. Его лучше использовать в местах критичных для скорости. С этим никто и не спорил. Просто ммх в гсс есть. Пусть и через билтины. А сколько он платформ поддерживает, так это красота
Добавлено через 1 минуту 18 секунд
Но, как и полагается в бесплатном компиляторе, нормальной документации к этому нет, а потому без поллитры не разобрать
А вот с этим я согласен на 100%
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.04.2009, 23:27
Попробую подвести итог

(to tux21)
Под линухом всё-таки используй gcc. В местах, критичных на производительность, попробуй переписать код или использовать ассемблерные вставки. Можно попробовать поиграть флагами оптимизаций, но, если нет глубокого понимания, что они делают, то скорее всего в этом месте улучшения производительности ты не получишь. К тому же если возникнут вопросы по gcc, то на форуме ты скорее всего сможешь получить ответ

(остальным, кому вопрос может показаться интересной, но в нашу дискуссию вникать было влом)
Сошлись во мнениях:
- под линухом альтернативы gcc скорее всего нету (по крайней мере среди бесплатного или известного платного)
- уровень gcc по надёжности качеству в принципе соотвествует уровню промышленного компилятора и его можно использовать для серьёзных разработок
- компилятор универсальный: на нём можно разрабатывать пользовательские приложения, низкоуровневые приложения класса ОС или драйверов, а так же высокопроизводительные коды, правда последнее почти наверняка потребует написания ассемблерных вставок или использования builin'ов, а потому этот вариант условно считаем только для экспертов

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

Со своей стороны хочу поблагодарить оппонента за аргументированный спор и потречанное на него время. Прсто хотябы потому, что нечасто в наши дни это удаётся, особенно на форуме
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
20.04.2009, 22:14
Лучший ответ Сообщение было отмечено как решение

Решение

Итак, начну с косяками gcc. Возможно не всё сразу, т.к. хочется это дело изложить аккуратно. Свалка с косяками оказалась приличной, но во многих случаях не было подробного описания что да как, а потому некоторые ситуации даже воспроизвести не смог. Отобрал несколько случаев не сильно замороченных и с подобранными короткими примерами. Возможно, что не всё сразу (терпения скорее всего не хватит)

C++
1
2
3
4
5
6
7
float f = 12.0;
unsigned long long b = 0x123;
 
main()
{
  return (f < -b);
}
В данном случае при правильном исполнении тест должен вернуть единицу. На gcc-2.95.3 (i386-linux и sparc-linux), gcc-3.3.2 (sparc-solaris) тест работает правильно. На gcc-3.4.6 (i386-linux и sparc-linux) и gcc-4.1.3 (i386-linux) работает НЕ правильно. Ковырялись в стандарте, вроде бы не нашли ни одного места, которое может быть неопределено

Более того, если мы тождествнно переделаем тест (минус уберём в статическую
инициализацию)

C++
1
2
3
4
5
6
7
float f = 12.0;
unsigned long long b = -0x123;
 
main()
{
  return (f < b);
}
то там, где тест ходил неправильно, он начинает работать правильно. Стало быть, ошибка компилятора

Рассмотрим фрагменты кода в "плохом" и "хорошем" случае. Стрелочками отмечу различия

"Плохой" случай:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
main:
        save    %sp, -112, %sp
        sethi   %hi(b), %i0
        mov     0, %o2
        mov     0, %o3
        call    __cmpdi2, 0
         ldd    [%i0+%lo(b)], %o0
        cmp     %o0, 0
        ble     .LL3
         or     %i0, %lo(b), %g1
        call    __floatdisf, 0
         ldd    [%i0+%lo(b)], %o0
.LL2:
        fnegs   %f0, %f8              <------------
        sethi   %hi(f), %g1
        ld      [%g1+%lo(f)], %f9     <------------
        fcmpes  %f8, %f9              <------------
        nop
        fbg     .LL7
         mov    1, %i0
        mov     0, %i0
.LL7:
        jmp     %i7+8
         restore
.LL3:
        # Здесь код, в котором при данных значениях мы не попадаем,
        # а потому его опускаю
"Хороший" случай:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
main:
        save    %sp, -112, %sp
        sethi   %hi(b), %i0
        mov     0, %o2
        mov     0, %o3
        call    __cmpdi2, 0
         ldd    [%i0+%lo(b)], %o0
        cmp     %o0, 0
        ble     .LL3
         or     %i0, %lo(b), %g1
        call    __floatdisf, 0
         ldd    [%i0+%lo(b)], %o0
.LL2:
        sethi   %hi(f), %g1
        ld      [%g1+%lo(f)], %f8     <------------
        fcmpes  %f0, %f8              <------------
        nop
        fbg     .LL7
         mov    1, %i0
        mov     0, %i0
.LL7:
        jmp     %i7+8
         restore
.LL3:
        # Здесь код, в котором при данных значениях мы не попадаем,
        # а потому его опускаю
К моменту метки .LL2 по результату вызова __floatdisf на регистре %f0 мы имеем значение (float)b - преобразование long long -> float делается через библиотечный вызов, т.к. на sparc v8 нет соотвествующей аппаратной инструкции. Далее в "плохом" случае стоит операция fnegs - плавающая negate (т.е. в регистр %f8 заносится величина "ноль минус %f0"). Далее идёт операция чтения переменной f на регистры %f8 и %f9 (разные регистры из-за того, что в "плохом" случае была дополнительная операция fnegs, а потому эти операции хоть и помечены стрелочкой, но фактически не отличаются). Далее идут операции fcmpes - сравнение двух плавающих регистров. Т.е. различия, если не считать другую раскладку регистров, только в том, что в "плохом" случае мы вычисляем fnegs. Что это означает на самом деле. У нас было сранение величин "f" и "-b", что по правилам языка Си выражается в сравнении величин "f" и "(float)(-b)". А код построен так, что сравниваются "f" и "-((float)b)". Сам понимаешь, что это не одно и то же

У себя эту ситуацию мы встретили в единичных случаях. Как показывает практика в "обычных" задачах (т.е. обычных прикладных программах) "тяжёлое" преобразование "uint64 -> floatXX" встречается нечасто, однако в счётных задачах типа моделирования физических процессов или каких-нибудь математических расчётов (особенно на фортране) - ситуация встречается сплошь и рядом. Поскольку ошибка присутсвует в компиляторе несколько лет (ибо как минимум это диапазон от "стабильной" версии 3.4.6 до 4.1.3), возможно, что счётными задачами компилятором gcc в мире активно не пользуются. Либо при этом используют какие-нибудь дополнительные опции оптимизации с плавающей арифметикой, при работе с которыми код строится по другому и данная ошибка не проявляется. Мы у себя это дело заткнули и приняли к сведению. Но на поиск ошибки, когда переходили от gcc-2.95.3 на gcc-3.4.6, потратили немало времени

Добавлено через 48 минут 17 секунд
======================================== ===================
======================================== ===================
======================================== ===================

Аналогично предыдущей, эта ошибка проявляется на gcc-3 и gcc-4 и не проявляется на gcc-2.95

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
 
double a = 0.5;
double b = 0.23;
double c = 6.0;
 
int main (void)
{
  double e, f;
 
  e = a - b;
  f = e * c;
 
  printf ("%.30f\n", f);
  return 0;
}
Различный результат мы получаем в зависимости от того, включены оптимизации, или нет. При этом вариант без оптимизаций правильный (т.е. в строгости соотвествует стандарту)

Code
1
2
3
4
$ gcc t.c && ./a.out
1.620000000000000106581410364015
$ gcc t.c -O2 && ./a.out
1.619999999999999884536805438984
Рассмотрим фрагменты кода

"Правильный" случай
Code
1
2
3
4
5
6
7
8
        fldl    a
        fldl    b
        fsubrp  %st, %st(1)
        fstpl   -24(%ebp)
        fldl    c
        fldl    -24(%ebp)
        fmulp   %st, %st(1)
        fstpl   -16(%ebp)
"Неправильный" случай
Code
1
2
3
4
5
        fldl    a
        fsubl   b
        fmull   c
        ...
        fstpl   4(%esp)
Вкратце поясню, что сие различие означает. На современных процессорах intel вся плавающая арифметика внутри процессора сделана через long double (хотя я предпочитаю назвать это термином "float80", соотвественно double - это "float64", а float - "float32"). Есть конечно и операции формата float32 и float64, но они сделаны для совместимости со старыми версиями процессора и работаю вроде бы как медленнее (я плохо разбираюсь в intel'e, но раньше помоему это вообще черех сопроцессор делалось). В данном случае мы фактически имеем сложное выражение в терминах float64: (a-b)*c. С точки зрения стандарта если это делается через float80, то должно выглядеть как: вычисляем ((float80)a - (float80)b), преобразуем его в float64 (в этом случае произойдёт потеря точности при переходе от float80 к float64), далее результат преобразуем в float80 и далее в терминах float80 умножаем на c. В интеле вроде бы как нет возможности сделать на регистре преобразование float80->float64 (все плавающие регистры у них 80-битные), а потому это делается через операции записи в память (в данном случае fstpl), которые совмещены с преобразованием float80->float64. В процессе оптимизаций пара операций store-load схлопывается и в этом месте преобразование не тождественно, т.к. при этом исключается обрезание точности. Т.е. результат становится более точным (т.е. математически более близким к правильному результату), однако неправильным с точки зрения стандарта, т.к. всё должно делаться с точностью float64

Понятно дело, что такие отличия критичны только для математических расчётов, где требуется высокая точность. Т.е. в обычных прикладных программах мы этой разницы не почуствуем, зато скорость исполнени будет выше, чем при "честных" расчётах. Однако опасность этого дела такая, что когда мы вычисляем "простое" выражение (т.е. одну арифметическую операцию, затем запись результата), то оно вычисляется с "честной" точностью, а когда вычисляем "сложное" выражение (несколько операций, а потом запись результата), то вычисления происходят с "НЕчестной" точностью. В этом месте начинает появляться некоторое отклонение, которое для некоторых алгоритмов при больших данных начинает накапливаться и со временем выливается в ощутимую разницу. Т.е. для программ типа 3d-studio это может очень хорошо стрельнуть

Теоретически в компиляторе есть какие-то опции, которые запрещают схлопавание пары плавающих store-load, на практике на коротких примерах вроде бы как работало, а на длинных возникают косяки. Один из косяков оказался принципиальным. Если у нас есть вызов плавающей стандартной функции типа sqrt, то в случае без оптимизаций компилятор оставляет вызов процедуры, а в случае с оптимизациями принудительно
заменяет вызов sqrt на __builtin_sqrt, который реализует через аппаратные интеловские операции вычисления корня. Если всё это находится в сложном выражении, то всё равно это делается через float80. В итоге мы так и не смогли побороть проблему (для нас в первую очередь критичным оказалось различное поведение в release'ной и отладочной версии программы).

Лечится просто - везде использовать long double. Но для большой программы везде всё поменять, это тоже куча потраченного времени, далее нужно везде менять значения в эталонных тестах - опять-таки огромная поетря времени. Для программ с большими данными это ещё и влечёт за собой увеличение потребления памяти (что для критично задач типа тех, что в реальном времени обрабатывают данные с локаторов). Ну и проблемы при совместном использовании разных компиляторов (которая косвенным образом появляется при использовании другого компилятора но при этом используется glibc, собранная gcc'ями) или же проблемы при переходе с одной версии компилятора на другую. Есть ли какие-то различия между gcc-3 и gcc-4 мы уже смотреть не стали, ибо заткнув всё через float80 уже не стали исследовать вопрос дальше
3
13 / 13 / 0
Регистрация: 29.10.2009
Сообщений: 71
06.11.2010, 18:24
под линукс intel c compiler бесплатен
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.11.2010, 18:24
Помогаю со студенческими работами здесь

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

Нужен компилятор под linux mint или linux ubuntu
Нужен компилятор под linux mint или linux ubuntu. Желательно голенький компилятор без редактора, и, было бы классно, без интерфейса (как...

Компилятор C++ под Ubuntu Linux 9.04
Здравствуйте, я немого найти компилятор С++ под линукс Никто из вас с єтим не сталкивался? Да и еще русского язіка нет Только английскй и...

Посоветуйте бесплатный C++ компилятор под Windows
Добрый день, уважаемые программисты Я изучаю С++ и мне нужен компилятор. Звучит странно? Ищу не среду разработки, а именно...

Посоветуйте, пожалуйста, адекватную графическую библиотеку под Linux
Присматривался в Qt - но не понравился большой объем исполняемых файлов. Кто-то рекомендовал SFML - но она, вроде, не столь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru