LINUX.ORG.RU

c: скорость компиляции


0

0

Такая проблема: надо некую функцию численно проинтегрировать. Есть эта самая функция в виде сишного выражения, дробно-рациональное выражение над double, pow() и log().

Проблема в том, что выражение это длиной десятки (даже сотни) мегабайт.

Если его в одну строку записать, gcc довольно быстро загибается, не влезая в 2 гига. По строчкам бить на суммы -- вроде, жрет, но ОЧЕНЬ долго (часы). Считает потом пару минут...

Короче, вопрос: что делать?

Может, есть какой-нибудь шустрый простой сишный компилятор, который выдаст ELF, линкабельный с gcc?

★★★★★

Ответ на: комментарий от anonymous

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

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

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

anonymous
()

Исползуй D! Скорость компиляции примерно в 20 раз быстрее, чем gcc.

Все известные мне компиляторы C либо медленные (gcc), либо windows-only (DMC)...

naryl ★★★★★
()

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

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

> ...что это за такое хитрое выражение, что его иначе как многомегабайтной строкой и не выразить?

Я ж писАл:

>...По строчкам бить на суммы -- вроде, жрет, но ОЧЕНЬ долго (часы). Считает потом пару минут...

Имелось в виду нечто типа:

tmp=0.0;

tmp+=x[2]+(pow(x[2],1.22)-x[7])/x[2]+log(x[2])-10.0;

tmp+=....;

....

return tmp;

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Алгоритм будет не намного сложнее трансляции в С

Ну, я ж не сам его в Си транслирую!

В принчипе, тоже выход, но меня интересует кроссплатформенность хотя бы по АМД и Интелу (включая Итаник).

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

>Имелось в виду нечто типа: >tmp=0.0; >tmp+=x[2]+(pow(x[2],1.22)-x[7])/x[2]+log(x[2])-10.0; >tmp+=....; Я имел в виду возможно ли завернуть эту бяку в цикл? Да, а что если попробовать fortran?

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

>Имелось в виду нечто типа:
 >tmp=0.0; 
>tmp+=x[2]+(pow(x[2],1.22)-x[7])/x[2]+log(x[2])-10.0; 
>tmp+=....; 
Я имел в виду возможно ли завернуть эту бяку в цикл? 

Да, а что если попробовать fortran?

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

> Исползуй D!

В принципе, вроде, то, что надо...

А можно его в СИ подлинковать? То есть, чтобы main() был СИшным?

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Я имел в виду возможно ли завернуть эту бяку в цикл?

Гы! Если б можно было, то и проблема не стояла бы.

> ...если попробовать fortran?

С него и начинали: Вегас-то на Фортране!. Все фортрановские компиляторы тормозят сильнее СИшных.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от marsijanin

> distcc ?

Не тот случай. distcc просто разбрасывает препроцесснутые файлы по разным компам и там звет тот же gcc.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

>А можно его в СИ подлинковать? То есть, чтобы main() был СИшным?

Насколько я знаю, Ди линкуется с Си нативно. Но в деталях не разбирался.

KRoN73 ★★★★★
()

Выражение то простое -- напиши простенький парсер который сгенерирует ast в бинарном виде -- и маленький сишный код пусть это дерево вычислит в data-driven fashion. Конечно результирующий код будет в 2-3 раза медленнее, чем прямо скомпилированное выражение.

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

> результирующий код будет в 2-3 раза медленнее...

Боюсь, больше чем в 2-3 раза медленнее...

Хотя, тоже выход. Надо подумать.

Дело в том, это не совсем мой проект, я просто коллегу консультирую, а он вообще не особо в программировании силен. Если я все же плотно подключусь, тогда буду плотнее думать. Наверное, действительно, самое эффективное будет в Гнутый ассемблер выражение гнать. Я сейчас прикинул -- gcc ассемблер с приемлемой скоростью жует.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от sdio

> Почему не скормить это калькулятору а-ля bc или dc ?

Пару миллиардов раз? :-)

Это интегранд от 8-мерного интеграла.

Die-Hard ★★★★★
() автор топика

А почему бы интерполяцию не сделать, просчитать в нескольких точках и аппроксимировать каким-нибудь методом? Я так понял, что в принципе расчёт по этому выражению провести можно.

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

> А почему бы интерполяцию не сделать, просчитать в нескольких точках и аппроксимировать каким-нибудь методом? Я так понял, что в принципе расчёт по этому выражению провести можно.

Оно все равно интегрируется -- т.е. то что ты предлагаешь -- это фактически угрубить сетку + использовать методы высокой степени -- видимо это и так делается по максимуму.

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

> Поддерживаю sdio

Боги, дайте мне йаду! :-)

Это текстовое выражение генерится Математикой -- она побыстрее bc считать умеет.

К сожалению, недостаточно быстро :(

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от dilmah

> ...то что ты предлагаешь -- это фактически угрубить сетку + использовать методы высокой степени -- видимо это и так делается по максимуму.

Разумеется!

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

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Tiny C Compiler

Да, спасибо. Я про него знаю -- он немного быстрее gcc, но мне нужны порядки...

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от dilmah

> ...и маленький сишный код пусть это дерево вычислит в data-driven fashion.

Да, так и поступим.

Выше я чушь написАл -- в магазин торопился, не подумал... :-) Конечно, в этом направлении и надо было думать с самомго начала.

Die-Hard ★★★★★
() автор топика

Я в аналогичной ситуации свой кодогенератор писал. Тупой такой, без оптимизации, поверх промежуточной стековой машины (а не трёхадрессной, как все Си на x86). Сотни мегабайт кода за секунды молотило, а по скорости работы результата от Си раза в 3 всего отставало в самом худшем случае на double-ах.

anonymous
()

>> Есть эта самая функция в виде сишного выражения, дробно-рациональное выражение над double, pow() и log().

Я так понимаю что тут от возможностей языка C используется где-то 0.1%... дак почему бы не взять уже упомянутый tcc и по максимуму из него всё выкинуть? Или вообще написать свой собственный простой компилятор. Или написать транслятор этого выражения в ассемблер и скармливать nasm'у, fasm'у или ещё чему-нибудь быстрому?

Deleted
()

Там же наверно есть общие подвыражения?

Видимо и компилятор Си много тратит на их поиск.

dilmah ★★★★★
()
Ответ на: комментарий от Die-Hard

> А можно его в СИ подлинковать? То есть, чтобы main() был СИшным?

У твоей программки на D будет сишная main сгенерированная компилятором, которая вызывает твою main на D. D имеет все сишные типы и линкуется с C с помощью extern(C).

http://www.digitalmars.com/d/1.0/interfaceToC.html

Через GDC, который примерно в 2 раза медленнее, чем DMD получишь реализацию для всех процессоров, на которых есть gcc. Но стандартная библиотека доступна только на Win32/Linux/MacOS. AFAIK DMD есть только для x86.

mailto: cy (at) ngs (dot) ru

naryl ★★★★★
()

интересно, а любимая всеми jvm осилит? ;)

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

> mailto: cy (at) ngs (dot) ru

Thanks,

Я пока проникся идеей dilmah. Попробую просто исходное выражение в Польскую строку скомпилить и на поддающихся примерах сравнить скорость ее интерпретации с вычислением C-компилированного выражения. Если будет сопоставимо, можно будет чего поумнее придумать с триадами или ast. Если нет -- посмотрю на D.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от alexru

> А как это выражение получается, если не секрет?

> Просто поиграться хочется :)

+1 Хотелось бы посмотреть поближе.

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

> А как это выражение получается, если не секрет?

Хирый фейнмановский интеграл в альфа-представлении, sector decomposition. Коллега придумал стратегию, когда разбиение (вроде) всегда сходится. Код написан на Математике. В принципе, она это дело интегрирует, но долго, и потом надо будет на пару порядков сложность повысить. Возникла идея сектора считать Вегасом. Уперлось в то, что фортранные выражения, которые Математика генерит, компилятся (если по памяти не вылетают) часами.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

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

bc/dc хоть и не компилер к примеру но ему наплевать на длину исходного кода. тоже касается postscript которому главное стек не переполнить.

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

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

Если он выражение оттранслирует в Форт, то он точно также его оттраслирует и в машкоды сопроцессора ;) А это будет уже намного быстрее.

...

Вообще, я бы именно так делал. Вариант с tmp += ... - очень хорошо ложится на сопроцессор.

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

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

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

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

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

...

Зато, кстати, можно объединить. Сам транслятор сделать на Форте. Т.е. входной поток парсить Фортом, но не в Форт, а сразу через форт-ассемблер в машкод. Другое дело, что я не знаю, есть ли под Линуксом популярные Форты с форт-ассемблером, поддерживающим инструкции FPU. SP-Forth под Linux в каком-то подвешенном состоянии и я не помню, что у него с плавучкой.

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

Я думаю что если Die-Hard поделится примером реального кода мы че нить изобретем

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

> Если он выражение оттранслирует в Форт, то он точно также его оттраслирует и в машкоды сопроцессора ;) А это будет уже намного быстрее.

Что-то мне имхается что посчитать это выражение интерпретатором будет эффективнее по времени чем оттранслировать и посчитать потом нативным кодом.

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

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

> Полезный выхлоп от процесса с трансляцией будет только если посчитать одно и то же надо минимум два раза.

Если кто не заметил -- его надо будет считать _миллиарды_ раз.

Еще раз про проблему, максимально подробно и медленно :). Есть сложная функция f(x), где x -- многомерный вектор . Ее нужно проинтегрировать по единичному (супер)кубику решеткой. То есть, надо вычислить значение этой функции во всех узлах решетки. Интеграл для начала 8-мерный, надо хотя бы пару знаков. Для наивного суммирования шаг решетки нужно делать 100, следовательно, число узлов равно (10^2)^8=10^16. Разумеется, в реальности мы используем продвинутую интерполяцию, поэтому число узлов меньше, но все равно исчисляется миллиардами.

Die-Hard ★★★★★
() автор топика

А gcc используется с оптимизатором или без? Имхо всякую оптимизацию надо отключать. Она может подвесить компиляцию.

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

>Что-то мне имхается что посчитать это выражение интерпретатором будет эффективнее по времени чем оттранслировать и посчитать потом нативным кодом.

В случае нецикличности и одноразовости вычисления - да, однозначно.

KRoN73 ★★★★★
()
Ответ на: комментарий от Die-Hard

>Если кто не заметил -- его надо будет считать _миллиарды_ раз.

Да, тогда - только компиляция в натив :)

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

> А gcc используется с оптимизатором или без?

Все оптимизации отключаются.

Похоже, с компиляцией кранты. Даже два порядка не помогут. Вчера запустил на большой машине более-менее "боевое" выражение (67 мег). Компилирует уже сутки, память потихонечку отжирается, уже 6 гиг скушано...

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