LINUX.ORG.RU

Вышел GNU Guile 2.0.7

 , , ,


1

3

Вышла новая версия реализации языка Scheme — GNU Guile 2.0.7. Несмотря на незначительное изменение номера версии, появились несколько интересных нововведений, а именно:

  • Полная поддержка инфиксных выражений (curly-infix-expressions). Теперь вместо (* a (+ b c)) можно писать {a * {b + c}}.
  • Поддержка разных опции чтения (read option) для разных портов.
  • Поддержка вложенных директив future.
  • Специальный синтаксис для добавления путей в переменные окружения GUILE_LOAD_PATH и GUILE_LOAD_COMPILED_PATH в конец списка путей, а не в начало.
  • Исправлен недочет в функции load-in-vicinity, которая не сканировала директории, установленные в переменной %load-compiled-path.
  • Исправлен порядок поиска расширений. Теперь Guile не изменяет для этого переменную окружения LD_LIBRARY_PATH.
  • Функция make-vtable-vtable помечена устаревшей, рекомендуется использовать make-vtable и <standard-vtable>.
  • Оптимизированы вызовы equal? и eqv? для случаев, когда один из аргументов — константа.
  • Новые предупреждения компилятора -Wduplicate-case-datum и -Wbad-case-datum.
  • Многочисленные незначительные улучшения и исправления ошибок.

>>> Подробности

★★★★★

Проверено: tazhate ()
Последнее исправление: maxcom (всего исправлений: 4)

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

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

Короче, Склифасовский, ты меня утомил. Я не собираюсь писать статью «Тривиальщина: тормоза Racket для анонимов». Если интересно - сам иди, смотри, учи мат.часть.

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

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

Конкретно как отменить инлайнинг в racket?

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

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

Почти на всех платформах он будет _медленнее_ для любой мало-мальски крупной функции. Т.к. кеш не резиновый. Но в садике про это не рассказывают, факт.

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

КО подсказывает, что если функция *совсем* пустая, то её таки дешевле инлайнить: 0 инструкций вместо 2х, + не придется терзать BTB. Но в остальном ты конечно прав.

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

И нахрена он там? Что он «улучшает» и как это у него получается?

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

Офигительный объем подготовительной работы: подцепить ELF, найти в нём функцию и нацелить на неё указатель.

Ты слепой чтоли? Тебе же сказано - надо обеспечить корректную работу рантайма с этой ф-ей. Если ты просто найдешь и подцепишь, то у тебя все сдохнет.

Код пустой функции (очевидно):

Лол, ф-я без аргументов.

Оригинальный код был таким:

А если в (start-atomic) ... (end-atomic) завернуть? Кстати, я надеюсь, ты не в Dr.Racket запускаешь?

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

Конкретно как отменить инлайнинг в racket?

Сделать set! на переменную.

(define (inline-loop n)
  (when (< n 1000000000) (inline-loop (sub1 n))))

(define not-inline-loop #f)
(define (not-inline-loop n)
  (when (< n 1000000000) (not-inline-loop (sub1 n))))
anonymous
()
Ответ на: комментарий от anonymous

Тьфу. Вот так:

(define (inline-loop n)
  (when (< n 1000000000) (inline-loop (sub1 n))))

(define not-inline-loop #f)
(set! not-inline-loop 
      (lambda (n)
        (when (< n 1000000000) (not-inline-loop (sub1 n)))))
anonymous
()
Ответ на: комментарий от rtvd

Почти на всех платформах он будет _медленнее_ для любой мало-мальски крупной функции.

И именно по-этому все нормальные компиляторы на практически всех платформах делают такую оптимизацию? Специально чтобы медленно работало?

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

Блять

(define (inline-loop n)
  (when (> n 0) (inline-loop (sub1 n))))

(define not-inline-loop #f)
(set! not-inline-loop 
      (lambda (n)
        (when (> n 0) (not-inline-loop (sub1 n)))))

(time (inline-loop 1000000000))
(time (not-inline-loop 1000000000))

спать пора

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

КО подсказывает, что если функция *совсем* пустая, то её таки дешевле инлайнить: 0 инструкций вместо 2х, + не придется терзать BTB. Но в остальном ты конечно прав.

Вообще-то если она в сторонней библиотеке, то заинлайнить её не получится.

Но инлайнится-то не она, а лямбда, через которую реализован цикл.

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

И именно по-этому все нормальные компиляторы на практически всех платформах делают такую оптимизацию? Специально чтобы медленно работало?

Они это не делают. Пример я приводил выше.

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

Ты слепой чтоли? Тебе же сказано - надо обеспечить корректную работу рантайма с этой ф-ей. Если ты просто найдешь и подцепишь, то у тебя все сдохнет.

Нука поведай нам, что же такого полезного делает рантайм, сверх того что делает ld-linux.so, чтобы обеспечить «корректную» работу?

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

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

А тебе не ясно, почему инлайнинг _не ускоряет_, а _замедляет_ работу программы?

Ты слепой чтоли? Тебе же сказано - надо обеспечить корректную работу рантайма с этой ф-ей. Если ты просто найдешь и подцепишь, то у тебя все сдохнет.

А ты невменяемый? Аналогичный код на C цепляет и запускает без проблем. Может все же дело в том, что Racket - альтернативно одаренный?

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

Лол, ф-я без аргументов.

Точно что лол. Аноним либо не понимает, почему она без аргументов, либо решил дрыснуть «знаниями». Ты что, не в курсе, что слово «функция» в контексте языка «С» эквивалентно слову «процедура»?

А если в (start-atomic) ... (end-atomic) завернуть?

Будет слегка медленней. 155 наносекунд вместо 150.

Кстати, я надеюсь, ты не в Dr.Racket запускаешь?

Нет, я запускаю из консоли.

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

Наверное, все же пораньше, чем появятся их аналоги для guile. Нет? ;-)

Virtuos86 ★★★★★
()

Одни предлагают программировать на своём придуманном байткоде(Forth) с раздельными стеками кода и данных, другие рисовать абстрактное дерево кода, которое мало того что почти не читаемо человеком, так ещё и изменяется макросами.

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

Scheme, guile и lisp в разы лучше чем удав3. А для веба сейчас активно осваивается ruby on rails.



Вообще-то guile - это диалект Scheme. А тот, в свою очередь, диалект семейства языков lisp.
А Ruby on Rails, конечно же, веб-фреймворк, и непонятно с какого боку он приплетен в это сравнение ЯП. Кстати, если уж удав так плох, то руби примерно там же валяется.

PS. Но мне интереснее Haskell и его применение к веб-разработке. Думаю опыт Erlang разработок представленных широко в сети будет полезен.


Не комментирую, но мне понравилось.

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

guile - это диалект Scheme

Guile is an interpreter and compiler for the Scheme programming language, a clean and elegant dialect of Lisp. Guile is up to date with recent Scheme standards, supporting the Revised5 and most of the Revised6 language reports (including hygienic macros), as well as many SRFIs. It also comes with a library of modules that offer additional features, like an HTTP server and client, XML parsing, and object-oriented programming.



Guile is an efficient virtual machine that executes a portable instruction set generated by its optimizing compiler... In addition to Scheme, Guile includes compiler front-ends for ECMAScript and Emacs Lisp (support for Lua is underway)... Guile's tools for parsing and compiling are exposed as part of its standard module set, so support for additional languages can be added without writing a single line of C.

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

нормальный порт

mingw.

/0

А ffmpeg, по-твоему, с помощью чего собирается? А ведь на него завязан не только опенсорс, но и тыщи проприетарных прог.

Признай, тупанул же.

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

OK. Этот факт, впрочем, только добавляет вистов некорректности откомментированному мной. Ты бы лучше его поправил.

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

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

Короче, Склифасовский, ты меня утомил. Я не собираюсь писать статью «Тривиальщина: тормоза Racket для анонимов». Если интересно - сам иди, смотри, учи мат.часть.

Вы меня оскорбить желаете или сделать комплимент?

Вы написали уже много интересного, быть может вам не составит большого труда ответить по существу?

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

Что-то ты темнишь.

Как можно темнить при выборе ответа из списка предложенных?

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

Вы написали уже много интересного, быть может вам не составит большого труда ответить по существу?

Мои посты, в отличии от твоих, и были по существу.

Если ты не умеешь читать или думать, то это не моя проблема.

А твоим учителем я становиться не намерен. Интересны вопросы оптимизации - будь добр, рой информацию сам.

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

Ты же понимаешь что без конкретного кода это просто невнятное кукареканье? Что вызывалось? Как вызывалось?

Код смотри в других моих постах Вообще-то он столь очедвиден, что приводить его не имело смысла. Но тебе видимо мало чего очевидно.

Ты забываешь про наличие рантайма. Так что в данном случае 100мс - может быть сверхпотимально. Учитывая, что Racket во время вызова FFI делает на порядок больше, чем SBCL, понятно, что и занимает этот вызов больше.

Это ты, петушок, про него забываешь. Суть как раз в том, что в racket - кривой рантайм (конкретно - реализация FFI и оптимизация кода).

Это все не говоря о том, что вызов функции через ффи - весьма узкий тест, который производительность платформы никак не показывает.

Это фундаментальный тест, который много чего говорит про производительность платформы. Если тебе он ничего не говорит - топай в сад.

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

Ты - троль или дебил. А может и то и другое сразу.

Если заинлайненная функция всегда быстрее функционально вызова и имеет смысл в том числе инлайнить циклы, то почему же racket не заинлайнил весь цикл до конца? А фигли, можно ведь сделать колбасу из миллиона элементов. Будет ведь быстрыее, не так ли? Но он, почему-то, заинлайнил пять вызовов. Почему пять? Пять это некая оптимальная глубина? Религиозная догма? Да, пожалуй она. Видимо они исповедывают тот же самый карго-культ, что и ты, малыш. Но видишь ли, никого твои бессмысленные танцы вокруг инлайнинга не прут.

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

Не sub1 а add1.

Если запускаю это:

#lang racket
(define (do_benchmark_1)
    (for ([i (in-range 1000000)]) #f))

(define (do_benchmark_2 i)
    (when (< i 1000000)
        (do_benchmark_2 (add1 i))))

(define do_benchmark_3 #f )
(set! do_benchmark_3
    (lambda (i)
        (when (< i 1000000)
            (do_benchmark_3 (add1 i)))))


(for ([i (in-range 10)])
    (time (do_benchmark_1))
    (time (do_benchmark_2 0)
    (time (do_benchmark_3 0))))

То вижу вот это:

cpu time: 2 real time: 1 gc time: 0
cpu time: 10 real time: 11 gc time: 0
cpu time: 14 real time: 15 gc time: 0
cpu time: 1 real time: 1 gc time: 0
cpu time: 11 real time: 11 gc time: 0
cpu time: 15 real time: 15 gc time: 0
...

Т.е. вариант с set! будет медленней, а вариант с for loop будет очень быстрым. Байткод для варианта с set! выглядит как-то странно. Мне не ясно сходу что оно пытается делать. Но там явно дело не в одном лишь отсутствии инлайнинга.

Если же внутри циклов идёт вызов FFI функции, то результаты выглядят так:

cpu time: 148 real time: 151 gc time: 0
cpu time: 155 real time: 157 gc time: 0
cpu time: 306 real time: 310 gc time: 0
cpu time: 148 real time: 152 gc time: 0
cpu time: 154 real time: 158 gc time: 0
cpu time: 305 real time: 311 gc time: 0

Т.е. код с set! в два раза медленней.

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

Они это не делают. Пример я приводил выше.

Где? Ссылку можно?

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

А тебе не ясно, почему инлайнинг _не ускоряет_, а _замедляет_ работу программы?

Так он _ускоряет_, а не _замедляет_.

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

Так он не аналогичный. Семантика кода разная. Сишкокод работает на ЦПУ, а код в Racket - на виртуальной лисп-машине.

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

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

Ты что, не в курсе, что слово «функция» в контексте языка «С» эквивалентно слову «процедура»?

Я-то вкурсе, но какой смысл вызывать foreign функцию без аргументов?

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

Это ты, петушок, про него забываешь. Суть как раз в том, что в racket - кривой рантайм (конкретно - реализация FFI и оптимизация кода).

Он не кривой, он очень сложный и высокоуровневый. В сишке вообще рантайма нет - по-этому там все быстро. В SBCL рантайм простой и примитивный (чуть сложнее чем в каком-нибудь шарпике или жабе). Racket по сравнению с этим технологически - как истребитель пятого поколения по сравнению с телегой.

Это фундаментальный тест, который много чего говорит про производительность платформы.

Это бессмысленный тест, который ничего не говорит ни о чем. Я же тебе уже объяснял - хорошие компиляторы _намеренно_ генерируют код который будет медленно работать на подобных тестах. В этом суть оптимизации.

Если заинлайненная функция всегда быстрее функционально вызова и имеет смысл в том числе инлайнить циклы, то почему же racket не заинлайнил весь цикл до конца?

Там нет цикла, там есть рекурсивная функция. Инлайнить «до конца» рекурсивные функции пока что никто не научился.

А фигли, можно ведь сделать колбасу из миллиона элементов. Будет ведь быстрыее, не так ли?

Да, будет быстрее, но совсем незначительно (т.к. время 1 итерации уже будет значительно превышать оверхед на вызов). Зато байткод сильно распухнет.

Но он, почему-то, заинлайнил пять вызовов. Почему пять? Пять это некая оптимальная глубина?

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

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

Так он _ускоряет_, а не _замедляет_.

Фантазируй дальше. Это забавляет.

Так он не аналогичный. Семантика кода разная. Сишкокод работает на ЦПУ, а код в Racket - на виртуальной лисп-машине.

Ага, на виртульной лисп-машине, запущенной на минбарском истребителе «белая звезда», летящем воевать с «тенями».

Во-первых там JIT.

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

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

Раскажи мне, что он там менеджит и за чем он там следит, когда просто вызывает ничего не делающую процедуру без аргументов. И главное, нахера он это делает.

Я-то вкурсе, но какой смысл вызывать foreign функцию без аргументов?

Ты серьёзно не понимаешь, или прикидываешься?

У тебя есть лучше способ поменять минимальные накладные расходы FFI вызова? Да? Ну так расскажи, может и дисер защитишь на эту тему.

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

> Он не кривой, он очень сложный и высокоуровневый. В сишке вообще рантайма нет - по-этому там все быстро. В SBCL рантайм простой и примитивный (чуть сложнее чем в каком-нибудь шарпике или жабе). Racket по сравнению с этим технологически - как истребитель пятого поколения по сравнению с телегой.

Ой-ли. Даже если он такой весь из себя сложный, то зачем было его таким делать? Чтоб этот «истребитель» истреблял дождевых червей, роя носом землю?

хорошие компиляторы _намеренно_ генерируют код который будет медленно работать на подобных тестах. В этом суть оптимизации.

Галоперидола этому пациенту.

Там нет цикла, там есть рекурсивная функция. Инлайнить «до конца» рекурсивные функции пока что никто не научился.

.. и электрошока тоже.

Да, будет быстрее, но совсем незначительно (т.к. время 1 итерации уже будет значительно превышать оверхед на вызов). Зато байткод сильно распухнет.

Пожалуй, без хирургического вмешательства не обойтись.

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

Конечно же, умный компилятор racket'а знает, каким будет время итерации, где вызывается подлючаемая из внешней библиотеки функция. Он способен делать астральную проекцию и читать Знание прямо из Хроник Акаши.

А вот тупой gcc этого не умеет, ничего не инлайнит, и потому позорно работает быстрее на два порядка. Вот деградация.

В общем, умывайся, тебе пора на лоботомию.

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

То вижу вот это:

надо было ноликов добавить, а то так ничего не видно:

#lang racket

(define n 100000000)

(define (do_benchmark_1)
    (for ([i (in-range n)]) #f))

(define (do_benchmark_2 i)
    (when (< i n)
        (do_benchmark_2 (add1 i))))

(define do_benchmark_3 #f )
(set! do_benchmark_3
    (lambda (i)
        (when (< i n)
            (do_benchmark_3 (add1 i)))))

(time (do_benchmark_1))
(time (do_benchmark_2 0))
(time (do_benchmark_3 0))

->
cpu time: 422 real time: 408 gc time: 0
cpu time: 422 real time: 411 gc time: 0
cpu time: 1343 real time: 1423 gc time: 0

Байткод для варианта с set! выглядит как-то странно. Мне не ясно сходу что оно пытается делать.

Что тут непонятного?

(begin
   (module m ....
     (require (lib "racket/main.rkt"))
     (define-values (_n) '1000000)
     (define-values (_do_benchmark_3) '#f)
     (#%apply-values
      |_print-values:p@(lib "racket/private/modbeg.rkt")|
      (set! (#%checked _do_benchmark_3)
        (lambda (arg0-5514)
          'do_benchmark_3
          '(captures: (val/ref #%modvars) (_do_benchmark_3))
          (if (< arg0-5514 '1000000) ((#%checked _do_benchmark_3) (add1 arg0-5514)) '#<void>))))
     (#%apply-values |_print-values:p@(lib "racket/private/modbeg.rkt")| ((#%checked _do_benchmark_3) '0))))

Но там явно дело не в одном лишь отсутствии инлайнинга.

Да нет, только в нем. Можешь просто попробовать сделать

(define (do_benchmark_2 i)
    (when (< i 1000000)
        (do_benchmark_2 (add1 i))))

в репле - тогда тоже не будет инлайнинга и будут аналогичные результаты (#%top символы нельзя инлайнить т.к. они могут быть переопределены). Еще можешь попробовать компилять с (enforce-module-constants #f), но я не уверен что оно в этом случае гарантированно уберет любой инлайнинг.

Т.е. код с set! в два раза медленней.

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

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

Фантазируй дальше. Это забавляет.

Я не фантазирую. Есть тесты, есть результаты тестов, есть существующие компиляторы, которые проводят инлайнинг. И есть петушок, который вопит «инлайнинг низя это зло!111!». Кому мне верить - фактам и профессионалам, пишущим компиляторы, или тебе-петушку?

Во-первых там JIT.

И что? Семантика кода соответствует семантике лисп-машины. И jit должен эту семантику сохранять, как и любая оптимизация.

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

Она имеет прямое отношение. Если семантика виртуальной машины далека от семантики реальной машины, на которой эта ВМ эмулируется, то ты что не делай - а будет просадка в производительности.

Раскажи мне, что он там менеджит и за чем он там следит, когда просто вызывает ничего не делающую процедуру без аргументов.

Кто тебе сказал, что он «просто вызывает процедуру без аргументов»? Я же тебе объясняю - foreig функцию нельзя «просто вызвать». Что тут непонятного?

И главное, нахера он это делает.

Чтобы сохранить семантику кода. рантайм никак не может предсказать, что foreign функция _ничего не делает_. По-этому считается что она может сделать все, что угодно. И вызывающий код должен быть к этому готов. Ну самый банальный пример - foreign функция может бросить исключение, по-этому надо сгенерировать код, который корректно перехватит это исключение в соответствии с протоколом рантайма. Или например - в ранатйме не используется машинный стек, там спагетти-стек, продолжения, возможность свободной работы со стекфреймами и т.п.. А в foreign функции - обычный машинный стек и надо обеспечить, чтобы все было «хорошо». А еще есть гц который должен специальным образом обрабатывать объекты, которые ушли в foreign или вернулись оттуда. А еще есть треды (зеленые и через future), а еще есть взаимодействие между инстансами ВМ. Все это контролируется рантаймом, но как только мы ушли в foreign код контроль теряется, и рантайм должен обеспечить по крайней мере возможность своего корректного падения, чтобы мы не получили рандомным образом КРОВЬ КИШКИ ГОВНО РАСПИДОРАСИЛО.

У тебя есть лучше способ поменять минимальные накладные расходы FFI вызова?

Непонел что? Имелось ввиду «померить»? Их вообще не надо мерить. Надо мерить скорость исполнения реальных задач, существенно использующих ффи. Вот например:

http://shootout.alioth.debian.org/u32/performance.php?test=pidigits

Там сишка, SBCL и Racket работают через вызовы GMP (foreign для общелиспа и ракетки). И я не вижу там какого-то значительного преимущества.

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

Ой-ли. Даже если он такой весь из себя сложный, то зачем было его таким делать?

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

Чтоб этот «истребитель» истреблял дождевых червей, роя носом землю?

Так он не роет.

Конечно же, умный компилятор racket'а знает, каким будет время итерации, где вызывается подлючаемая из внешней библиотеки функция. Он способен делать астральную проекцию и читать Знание прямо из Хроник Акаши.

Нет, не знает. Он не оценивает время итерации, потому что незачем. Как уже ясно из вышесказанного - инлайнинг по крайней мер не замедлит выполнения кода, по-этому ограничивается инлайнинг экономией на величине байткода. Вот функция и раскрывается, пока не станет «слишком большой». Если итерация быстрая - будет профит, если медленная - то не будет, но и просадки в производительности не будет.

А вот тупой gcc этого не умеет, ничего не инлайнит

С чего ты взял что он не инлайнит? инлайнит.

потому позорно работает быстрее на два порядка.

Он работает быстрее на два порядка, потому что просто не делает того, что делает тот же Racket или SBCL. Из-за той самой семантики рантайма, которая в случае с сишкой фактически совпадает с семантикой исполняющей машины.

Если потребовать от кода на сишке семантики кода на лиспе, то он не будет работать быстрее на два порядка. Он вообще не будет работать быстрее - он будет работать _медленнее_.

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

Я не фантазирую.

Пруф в студию.

Пруф того, что ты - даун, я уже привёл (в виде программы на C и её скомпилированного вида).

Там сишка, SBCL и Racket работают через вызовы GMP (foreign для общелиспа и ракетки)

Ты даже тупее чем я думал.

GMP это настолько фундаментальная библиотека, что она как правило используется напрямую . Есть возражения? Приведи пример кода из racket, где видно, что GMP используется через стандартный FFI интерфейс.

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

я уже привёл (в виде программы на C и её скомпилированного вида).

возьми и скомпилируй программу с -O3, будет тебе инлайнинг.

GMP это настолько фундаментальная библиотека, что она как правило используется напрямую . Есть возражения? Приведи пример кода из racket, где видно, что GMP используется через стандартный FFI интерфейс.

Ты совсем тупой? сам не могу заглянуть в код?

http://shootout.alioth.debian.org/u32/program.php?test=pidigits&lang=rack...

(define libgmp (ffi-lib "libgmp"))
(define-syntax-rule (defgmp op type ...)
  (define op (get-ffi-obj (format "__gmpz_~a" 'op) libgmp (_fun type ...))))
(define-cstruct _mpz ([alloc _int] [size _int] [limbs _pointer]))
(defgmp init_set_ui _mpz-pointer _ulong -> _void)
(defgmp set_ui _mpz-pointer _ulong -> _void)
(defgmp get_ui    _mpz-pointer -> _ulong)
(defgmp add       _mpz-pointer _mpz-pointer _mpz-pointer -> _void)
(defgmp mul       _mpz-pointer _mpz-pointer _mpz-pointer -> _void)
(defgmp mul_ui    _mpz-pointer _mpz-pointer _long        -> _void)
(defgmp addmul    _mpz-pointer _mpz-pointer _mpz-pointer -> _void)
(defgmp addmul_ui _mpz-pointer _mpz-pointer _ulong       -> _void)
(defgmp submul_ui _mpz-pointer _mpz-pointer _ulong       -> _void)
(defgmp tdiv_q    _mpz-pointer _mpz-pointer _mpz-pointer -> _void)
(defgmp cmp       _mpz-pointer _mpz-pointer              -> _int)
anonymous
()
Ответ на: комментарий от rtvd

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

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

Да он совсем ебнутый. видимо, он думал, что никто не заглянет по ссылке, никто не обратит внимания на extern и т.п.

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

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

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

Такому ебанату как ты до сих пор невдомёк, что я не желаю, чтобы эту функцию инлайнило?

Ах да, ты - спец сравнивать хер с морковью. Извини, нам не по пути. Я тут сравниваю вызов функции, находящейся в shared library, в разных языках. Это типа для справки.

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

«Там в бенчмарке GMP вызывается через FFI. Что значит „напрямую“?»

Там написано «In addition to language specific multiprecision arithmetic, we will accept programs that use GMP.». Где тут требование вызывать GMP через FFI? А в том же GHC эта арифметика делается через GMP, но FFI там нет и близко.

Это так, чисто для справки.

Ну а далее, в этом тесте очевидно расходы на вызовы FFI будут несущественны по сравнению с собственно временем исполнения функций GMP. Так что этот бенчмарк абсолютно не эквивалентен моему, т.к. он меряет другое.

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

Ах да, ты - спец сравнивать хер с морковью. Извини, нам не по пути. Я тут сравниваю вызов функции, находящейся в shared library, в разных языках.

Ты давай дурачком не прикидывайся. Мы проверяли инлайнит ли функции гцц (ты же доказываешь что не илайнит, т.к. это медленно). вот и давай проверим заинлайнит ли он ее, если _может_ заинлайнить.

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

Так что этот бенчмарк абсолютно не эквивалентен моему, т.к. он меряет другое.

А никто и не говорил, что он эквивалентен. Еще раз - твой бенчмарк ничего толкового не меряет. По-этому он хуевый. А хороший бенчмарк - он меряет производительность задач, близких ИРЛ. Так вот, дебилушка, ирл «расходы на вызовы FFI будут несущественны по сравнению с собственно временем исполнения функций». Именно по-этому измерять расходы на чистый вызов - полное ебанатство. Потому чот к реальности такой бенчмарк не имеет отношения. Какой смысл вызывать через ffi функцию, которая блять не делает ничего? Нахуй не нужно. И мерить производительность такого вызова тоже нахуй не нужно. На практике через ffi дергаются ф-и, которые делают нечто полезное.

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

возьми и скомпилируй программу с -O3, будет тебе инлайнинг.

gcc -std=c99 -o test2 -O3 test2.c -L. -ltest
objdump -d -S test2|less

Где здесь инлайнинг, детка?

  0000000000400540 <main>:
  400540:       53                      push   %rbx
  400541:       bb 00 ca 9a 3b          mov    $0x3b9aca00,%ebx
  400546:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40054d:       00 00 00 
  400550:       e8 db ff ff ff          callq  400530 <do_test@plt>
  400555:       48 83 eb 01             sub    $0x1,%rbx
  400559:       75 f5                   jne    400550 <main+0x10>
  40055b:       31 c0                   xor    %eax,%eax
  40055d:       5b                      pop    %rbx
  40055e:       c3                      retq   
  40055f:       90                      nop

Ты совсем тупой? сам не могу заглянуть в код?

Да нет, до тебя далеко.

Я тебе намекнул, что в racket уже есть поддержка длинной арифметики.

Открой его исходники, глянь на racket/src/gmp/, может поумнеешь.

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

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

А я чтото говорил про хаскель или какието другие решения?

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

Ты давай дурачком не прикидывайся. Мы проверяли инлайнит ли функции гцц (ты же доказываешь что не илайнит, т.к. это медленно). вот и давай проверим заинлайнит ли он ее, если _может_ заинлайнить.

Тебе прикидываться и не нужно.

Естественно, простые функции он инлайнит и правильно делает. Но над циклами он не извращается. Это - конёк racket.

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

Где здесь инлайнинг, детка?

А в racket где? тоже нету. Проблемы?

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

Естественно, простые функции он инлайнит и правильно делает.

Вот и racket простые функции инлайнит и правильно делает. Какие проблемы, дурашка? Почему эквивалентное поведение gcc у тебя не вызывает вопросов, а racket - вызывает?

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