LINUX.ORG.RU

CL быстрее прочих :)


0

3

Новый, и как всегда красивый, пример кодогенерации от swizard

http://swizard.livejournal.com/158763.html

на этот раз решение задачи http://shootout.alioth.debian.org/u32q/benchmark.php?test=fannkuchredux&lang=...

★★★★★

Последнее исправление: psv1967 (всего исправлений: 1)
Ответ на: комментарий от ugoday

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

Гыгы. Дух Тьюринга запретил, да?

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

>***зописывает: Лиспособы --- суть нищеброды несчастные.

И ты тоже, крошка. Подари мне, незнакомому левому дяде 200 баксов или нишеброд.

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

>Freepascal - это что такое? GNU Pascal знаю, FreePascal - нет.

Реализация паскаля, которая в этом шутауте называется Pascal Free Pascal.

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

>>> «трюк» который получается несколько раз подряд и с разными задачами уже не трюк

Цирковые акробаты с тобой не согласятся %)

с _разными_ же задачами...

Блин, ты принял аналогию слишком всерьез.

в одном случае занести рояль на 12й этаж, а во втором сдать печатать на пишущей машинке со скоростью 200 с/мин?

Слово swizard'у:

«С хамелеонами у меня такой фокус, разумеется, не прошел: там все данные и так фиксированные, а перфоманс упирается в синхронизацию потоков. Но с „блинами“ фишка сработала».

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

>> Freepascal - это что такое? GNU Pascal знаю, FreePascal - нет.

Реализация паскаля, которая в этом шутауте называется Pascal Free Pascal.

Ну то есть ты тоже не знаешь... пойду спрошу гугль.

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

> какая-то функция получила std::istream &in и пытается сделать

in>>int_value, то угадай, вызов какого оператора подставить

компилятор? Всегда istream::operator>>.



К.О. в восторге. И что? Что не так?

бусте написали свою IO систему, потому что в плюсовке она

пришибленная на всю голову



Пардон, я давно уже буст не смотрел, можно ссылку на эту систему? А то я только помню boost::iostreams, но это точно «не своя система», а вся те же плюсовые потоки.

И я совсем не понял, как ты отделяешь буст от «плюсовки», может мы о разных бустах говорим? Или о разных плюсовках?

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

>У тебя на балконе может стоять подводная лодка, но нам это также неочевидно, как и факт запускания кода с %esi на 64-битной оси.

Интересно, а как по-твоему завершится 64-битная программа, использующая нижние 32 бита указателя для записи туда значения?

Хватит нищебродить, иди работать лиспером.

То есть ты не готов вот так вот взять и пожертвовать 200 баксов незнакомому дяде? А почему я тогда должен побежать в магазин и выложить 200 баков за нахелем, еще сколько-то за мать и за память по первому слову какого-то безграмотного дядечки, отрицающего святое святых: выравнивание?!

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

>К.О. в восторге. И что? Что не так?

Дело в том, что поставленная задача нерешаема поверх плюсовой библиотеки ввода-вывода. Так или иначе, придется изобретать новую сущность.

И я совсем не понял, как ты отделяешь буст от «плюсовки»

Я не совсем понял: ты спрашиваешь меня, почему я отделяю boost от libstdc++? Потому что это разные вещи.

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

> «С хамелеонами у меня такой фокус, разумеется, не прошел: там все данные и так фиксированные, а перфоманс упирается в синхронизацию потоков. Но с „блинами“ фишка сработала».

ишо не вечер, следите за обсуждением... там mv объясняет как афинити крутить (как всегда блин без примеров :( )

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

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

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

Который, в общем-то, к Лиспу не имеет никакого отношения.

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

Кстати, еще мне этот алгоритм не нравится тем, что shootout превращается из места сравнения языков программирования в место сравнения программистов.

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

> Который, в общем-то, к Лиспу не имеет никакого отношения.

могу только еще раз попросить его (код) написать на C++

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

>Кстати, еще мне этот алгоритм не нравится тем, что shootout превращается из места сравнения языков программирования в место сравнения программистов.

А как ты предлагаеш сравнивать языки программирования и исключить влияние качества программистов? К слову не только языков но и их реализаций, что тоже не совсем честно, зато жизненно.

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

По моему в подходе swizard наоборот всё доступно: «чего вижу, то и пишу». Весь фокус _по _моему_ в том что пишется параметризированный код. Причем максимально простой в первом варианте.

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

>> Который, в общем-то, к Лиспу не имеет никакого отношения.

могу только еще раз попросить его (код) написать на C++

Могу только еще раз сказать, что мне неинтересны олимпиадные задачи (это говоря уже о том, что я практически не знаю CL).

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

> А как ты предлагаеш сравнивать языки программирования и исключить влияние качества программистов?

Для начала, я предлагаю реализовывать одни и те же алгоритмы.

Исключить влияние программиста нельзя, но делать из сравнения языков сравнение программистов - это как бы похеривает цель great _language_ shootout. Назовите это «олимпиадой по программированию», которой и является соревнование программистов.

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

и соревноваться у кого for() быстрее сделан? :) всё сведется к наиболее убогому в средствах выражения языку.

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

> и соревноваться у кого for() быстрее сделан? :)

Примерно так.

всё сведется к наиболее убогому в средствах выражения языку.

Неужели тебе (да хоть кому-нибудь) правда интересно, какой язык самый быстрый? Лично мне интересно соотношение эффективности языка к его мощности. И результаты реализации одного алгоритма дают неплохую аппроксимацию.

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

> Дело в том, что поставленная задача нерешаема поверх плюсовой

библиотеки ввода-вывода. Так или иначе, придется изобретать новую

сущность



Почему? Какую?

P.S. Не, я завязываю рассуждать на тему CL vs. C++ с человеком, который ни в том, ни в другом ничего не соображает.

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

>Кодогенерация вообще редко бывает полезно и кажется только swizard занимается этим постоянно. А у CL множество других достоинств.

В общем-то, у меня это тоже вызывает некоторое удивление. Кодогенерация нужна в ограниченном числе случаев, а у swizard она используется и там, где (как мне кажется) можно и обойтись без нее.

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

> наркоман, и не лечишься... в _сумме_ 50. А так от старта 12.9сек

да, сорри

но насчет наркомана ты слишком хватил: всего лишь простуда, в крайнем случае грипп :-)

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

Интересно, а как по-твоему завершится 64-битная программа, использующая нижние 32 бита указателя для записи туда значения?

Если в esi лежит половинка от 64-битного адреса, то как бохх на душу положит.

То есть ты не готов вот так вот взять и пожертвовать 200 баксов незнакомому дяде? А почему я тогда должен побежать в магазин и выложить 200 баков за нахелем, еще сколько-то за мать и за память по первому слову какого-то безграмотного дядечки, отрицающего святое святых: выравнивание?!

Я не заставляю никого ничего делать. Это кагбе намёк на то, что выравнивание на платформе x86 кануло в лету.

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

> всего лишь простуда, в крайнем случае грипп

сходные симптомы подвели... ну не волчанку же было ставить в качестве диагноза? :)

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

>Это кагбе намёк на то, что выравнивание на платформе x86 кануло в лету.

Все равно что говорить «флеш канул в лету, потому что в HTML5 появился тег video». Какой идиот будет покупать себе домой xeon?

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

> В общем-то, у меня это тоже вызывает некоторое удивление. Кодогенерация нужна в ограниченном числе случаев, а у swizard она используется и там, где (как мне кажется) можно и обойтись без нее.

Мне кажется это достойная реакция на применение «везде» ООП «индустриальными» программистами.

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

Все равно что говорить «флеш канул в лету, потому что в HTML5 появился тег video».

Всё равно, что говорить: «Выравнивание - это блажь. На i4004 его не было, на i7 тоже.»

Какой идиот будет покупать себе домой xeon?

Идиоты вполне покупают себе i5.

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

Ага,быстрее

внимательно следим за минимальными значениями boxplota :) А там и медиану подтянем, или что там «статистики» применили?

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

>Идиоты вполне покупают себе i5.

Может я чего-то не понимаю, но i5 значительно дешевле, чем xeon. Фактически, один xeon стоит столько, сколько системник с i5 и игровой видеокартой на борту. Или я что-то путаю?

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

Может я чего-то не понимаю, но i5 значительно дешевле, чем xeon. Фактически, один xeon стоит столько, сколько системник с i5 и игровой видеокартой на борту. Или я что-то путаю?

Сессно пукаешь. Я и говорю, что нехалемы нонче дешёвые, в 10" буки ставят. i7@970 за штуку зелени не обязательно покупать, что быть гордым обладателем нехалема.

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

> Трудно вообще что-либо обсуждать с упертым фанатиком

который не может даже прочитать, что ему пишут.


Ссылку пожалуйста, с подтверждением того, что я «упёртый фанатик».

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

Судя по твоим постам про потоки в C++ ты очень плохо представляешь что они такое и как внутри устроены. В этом плане то, что ты их характеризуешь как «г...» очень точно показывает твоё отношение ко всему, чего ты не понимаешь. А не понимаешь ты многого...

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

>А не понимаешь ты многого...

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

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

А там и медиану подтянем, или что там «статистики» применили?

Малыми средствами такие вещи не делаются :) SBCL не гепард и раскрашиванием его в пятнышки не заставишь бегать на вроде C++. Т.е. да - на разных языках можно написать алгоритмы разной эффективности и это ничего не говорит о самих языках; есть подходы которые возможны в CL, но невозможны во многих других языках (равно как что-то невозможно в CL). Но сам рантайм так устроен у SBCL что на многих одинаково сделанных алгоритмах (где это возможно) он никак не сможет обогнать ATS или C++ (или Haskell на задачах из серии Concurency).

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

> SBCL не гепард и раскрашиванием его в пятнышки не заставишь бегать на вроде C++. Т.е. да - на разных языках можно написать алгоритмы разной эффективности и это ничего не говорит о самих языках; есть подходы которые возможны в CL, но невозможны во многих других языках (равно как что-то невозможно в CL). Но сам рантайм так устроен у SBCL что на многих одинаково сделанных алгоритмах (где это возможно) он никак не сможет обогнать ATS или C++ (или Haskell на задачах из серии Concurency).

А можно поподробнее про накладные расходы рантайма SBCL. И воопче, научите меня лисп оптимизировать.
Я тут на коленке играюсь с факториалом: написал на ANTLR парсер C-подобного языка, написал на таком mini C факториал, собрал gcc, запустил, померял.
Потом взял в руки парсер, получил на выходе AST, через AST.toStringTree() его распечатал в виде S-выражений, indent-ом сделал pretty printing (или дописал в парсер десяток строчек). Получил тот же факториал на «типа лиспе», в котором не реализованы Си-токены.
Пару дней поигрался с макросами в SLIME => написал макросы, транслирующие такой «типа лисп» в нормальный лисп.
Теперь делаю (load cminus.lisp) (load factorial.lisp) и получаю на выходе оттранслированный сишный main () с оттранслированным факториалом (для начала, итеративным, без рекурсии вообще)
Меряю время, усредняю, конпелирую такой main, опять меряю, сравниваю с Си вариантом => стабильно получаю примерно раза в 3 SBCL вариант медленнее.
Интересно, почему?
Нужна какая-то особая магия с (declare fixnum)? В моих наколеночных макрах получается информация о типах в функциях пока воопче не используется, выходит, overhead идёт из fixnum vs. bignum?

Как-то можно по-быстрому локализовать почему вариант раза в 3 медленее, без (disassemble 'main) и без (sb:profile 'main) ?

ЗЫ. Ещё хочу схему взять, Gambit например, перегнать её в Си и сравнить с исходным факториалом.

Откуда берётся типичный лисповый оверхед, алгоритм-то один и тот же оттранслированный с одного языка на другой?

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

Откуда берётся типичный лисповый оверхед, алгоритм-то один и тот же оттранслированный с одного языка на другой?

Конпеляторы разные. В gcc есть peephole и ssa, в sbcl нету. Вернее, первое только-только начало появляться, а второе на вряд ли в скором времени кто серьёзно возьмётся делать.

mv ★★★★★
()

Ещё что интересно. У автора используется везде sb:thread. green threads не быстрей ли будут?

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

ОК, тогда наверно полезнее будет поиграться с Gambit-ом и им сгенерированным сишечным исходником.

Такого рода тестом наверное, можно было бы сравнить отдельно чисто языки и реализации между собой — а то сравниваются то ли алгоритмы, то ли программисты =)

Интересуют метафизические свойства лиспа вроде: вот мы тупо оттранслировали алгоритм с вижуал бейсика на лисп, и никак не можым ускорить его в 10500 раз, взяв исполняющий лисп рантайм заместо бейсячного. А если вот так перепишем, используя особую лисповую магию — алгоритм трансформируется и волшебным образом ускоряется ощутимо.
И лисп, дескать, крут — если такого рода «переписывания» удастся обобщить и запрограммировать, а то инсайты и особая кодогенерационная магия это конечно круто, а вот как бы это всё по кнопке делать, типа делай раз, делай два, а то как-то по старинке выходит: уткнулись в пределы, думаем, оптимизируем и смотрим в disassemble.

swizard крут, конечно, но этот вот пунктик

Представить себе, как должна выглядеть максимально производительная программа, при условии фиксированных входных данных (все константы).


чем-то напоминает АРИЗ: «Представим себе идеальный конечный результат» — а у меня на этой фазе всё кони сферические вылазят, померяли — то слоны, то носороги.

Какие-то общие принципы оптимизации именно лиспа нужны, чтоле. Чтобы их запрограммировать.

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

SSA зато вроде бы есть в LLVM, и для Gambit точно была генерация в LLVM (какой-то древний, 2.2 вроде), а для SBCL вроде бы тоже что-то подобное было (http://repo.or.cz/w/sbcl/llvm.git/blob/HEAD:/README.LLVM).

Шутаут непонятный, однако. Что сравнивается: языки, реализации конпеляторов и рантаймы реализаций, алгоритмы или программеры? =)

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

На шутауте в пределе тестируется способность компиляторов порождать максимально сжатый и эффективный цикл. На кой хрен этот шутаут swizard'у сдался - не понятно. Достаточно действительно посмотреть пару раз на дизассемблированный код и понять, где у компилятора предел возможностей.

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

Шутаут непонятный, однако. Что сравнивается: языки, реализации конпеляторов и рантаймы реализаций, алгоритмы или программеры? =)

Длина.

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

Длина чего и в каких попугаях?

Мужского полового х., в имперских дюймах.

mv ★★★★★
()

Кстати, вопрос не совсем по теме, но здесь же собрались матерые практики CL... насколько хорошо взаимодейчтвует отладчик с макросами? Интересует пошаговое исполнение.

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

Откуда берётся типичный лисповый оверхед, алгоритм-то один и тот же оттранслированный с одного языка на другой?

Ну вот вы читали SICP? Там выражения вроде (+ 1 2 (* 3 4)) рисовались в виде деревьев:

  +
 /|\
1 2 *
   / \
  3   4

Т.е. примерно понятно как по такой консистентной структуре данных (AST) пройтись операцией eval, или как транслировать её в инструкции какой-нибудь state machine.

Теперь берём (в любом лиспе) форму которая создаёт окружение (envionment, очень важная штука) - то есть создаёт связанные переменные (bind vaiables), это может быть let, lambda, defun, и прочие прочие:

(let ((a 1)
      (b 2))
  (+ a b))

Такие штуки принято представлять уже не деревом а графом - чтобы помечать связи переменных:

     _let_
    /     \
   .       +
  / \     / \
a=1 b=2  a   b
|   |    ^   ^
`---+----^   ^
    |        ^
    `--------^

Как особенность всех динамически типизированных, в этом графе a и b - изначально вроде числа, но в процессе выполнения могут быть чем угодно - понятно, что тут будет оверхед (одно дело свести всё к арифметике регистров, а другое - имет обобщённый lispobj который может быть чем угодно). Какие варианты:

1) Заметить типы переменных, те функции в которых они используются и _вывести_ все типы автоматически. В CL так не принято.

2) Вмесот этого можно тэгировать дерево типами вручную:

        ______let______
       /               \
   ___.___              + :: fixnum
  /       \            / \
a=1::bit b=2::fixnum  a   b
|        |            ^   ^
`--------+------------^   ^
         |                ^
         `----------------^

т.е.

(let ((a 1)
      (b 2))
  (declare (type bit a) (type fixnum b))
  (the fixnum (+ a b))

Как я уже заметил связные переменные появляются в больших количествах в разных формах - все их нужно тегировать если есть резон гнаться за производительностью, ну и не забыть объявить глобальные политики:

(declaim (optimize (speed 3) (debug 0) (space 0) (safety 0))

В общем - речь просто о прописывании типов и в том чтобы позволить компилятору проводить все агрессивные оптимизации. Просто берём и прибиваем все типы гвоздями - как будто у нас не динамически типизированный язык а статически (ну так и есть). Для облегчения этой задачи можно использовать макросы - генерировать декларации типов. (не нужно декларировать типы аргументов макросов (т.к. они не попадают в macroexpand)). Что ещё можно делать кроме типов?

1) Читать стандарт про declaim/proclaim/declare (например инлайнить функции, объявлять время жизни объектов).

2) Использовать define-compiler-macro

3) В крайнем случае - source transfomations и VOPs для SBCL.

Вот ссылка:

http://fprog.ru/2010/issue4/vitaly-mayatskikh-lisp-abstractions-on-steroids/

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

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