Size: a a a

Clojure — русскоговорящее сообщество

2020 January 11

RN

Ryzhikov Nikolay in Clojure — русскоговорящее сообщество
cnuernber/libpython-clj: libpython bindings into the techascent ecosystem
https://github.com/cnuernber/libpython-clj
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Если кто не видел, всех причастных просят поучаствовать в опросе
https://www.surveymonkey.com/r/clojure2020
источник

T

The2lb3oz4dr10½grOfHedgehogs in Clojure — русскоговорящее сообщество
Sergey Trofimov
Если кто не видел, всех причастных просят поучаствовать в опросе
https://www.surveymonkey.com/r/clojure2020
А результаты когда будут/где посмотреть?
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
результаты будут позже
можно будет посмотреть здесь https://clojure.org/news/2020/01/07/clojure-2020-survey
источник

A

Aleksey @cheatex in Clojure — русскоговорящее сообщество
Dima Fomin
ну это то да, в одном треде это понятно. И если сделать 100 таких тредов, тоже будет в 100 раз быстрее. Но мне то надо собрать значения из 100 тредов :/
Попробую еще из 100 тредов слать в неблокирующую очередь в один тред и в нем суммировать.
*Adder сделаны специально для складывания в несколько потоков  jdkшной командой. Я бы не рассчитывал получить что то заметно лучшее просто играя примитивами меньше чем за  несколько месяцев. Только если хитро юзануть особенности домена.
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Dima Fomin
вот я поигрался, у меня получилось, что вот так быстрей всего на 4 домашних ядрах
вот распараллеливание инкремента с последующим суммированием с помощью core.async

(criterium/quick-bench
   (loop [i (int 0)
          n (int 1e8)]
     (if (pos? n)
       (recur (unchecked-inc i) (unchecked-dec n))
       i)))
Evaluation count : 12 in 6 samples of 2 calls.
            Execution time mean : 59,346057 ms
   Execution time std-deviation : 365,605235 µs
  Execution time lower quantile : 58,905549 ms ( 2,5%)
  Execution time upper quantile : 59,869274 ms (97,5%)
                  Overhead used : 1,808581 ns
=> nil
(criterium/quick-bench
   (let [limit (int 1e8)
         parallelism 100
         chunk-size (int (/ limit parallelism))
         from (async/to-chan (vec (repeat parallelism 1)))
         to (async/chan parallelism)
         work (async/pipeline parallelism
                to
                (map (fn [_]
                       (loop [i (int 0)
                              n (int chunk-size)]
                         (if (pos? n)
                           (recur (unchecked-inc i) (unchecked-dec n))
                           i))))
                from
                true)]
     (do
       (async/<!! work)
       (async/<!!
         (async/reduce + 0 to)))))
Evaluation count : 42 in 6 samples of 7 calls.
            Execution time mean : 15,824584 ms
   Execution time std-deviation : 189,562450 µs
  Execution time lower quantile : 15,691798 ms ( 2,5%)
  Execution time upper quantile : 16,145688 ms (97,5%)
                  Overhead used : 1,808581 ns

Found 1 outliers in 6 samples (16,6667 %)
 low-severe   1 (16,6667 %)
Variance from outliers : 13,8889 % Variance is moderately inflated by outliers
=> nil
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
ускорение в 4 раза по сравнению с инкрементом в один проход
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
параллелизм в 1000 хуже чем в 100
впрочем у асинка дефортный пул вроде 8
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
ну то есть параллелизм выше 8 в данном случае смысла не имеет
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
понятно, что использование атомов для координации между потоками сразу ломает всю красоту
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Sergey Trofimov
вот распараллеливание инкремента с последующим суммированием с помощью core.async

(criterium/quick-bench
   (loop [i (int 0)
          n (int 1e8)]
     (if (pos? n)
       (recur (unchecked-inc i) (unchecked-dec n))
       i)))
Evaluation count : 12 in 6 samples of 2 calls.
            Execution time mean : 59,346057 ms
   Execution time std-deviation : 365,605235 µs
  Execution time lower quantile : 58,905549 ms ( 2,5%)
  Execution time upper quantile : 59,869274 ms (97,5%)
                  Overhead used : 1,808581 ns
=> nil
(criterium/quick-bench
   (let [limit (int 1e8)
         parallelism 100
         chunk-size (int (/ limit parallelism))
         from (async/to-chan (vec (repeat parallelism 1)))
         to (async/chan parallelism)
         work (async/pipeline parallelism
                to
                (map (fn [_]
                       (loop [i (int 0)
                              n (int chunk-size)]
                         (if (pos? n)
                           (recur (unchecked-inc i) (unchecked-dec n))
                           i))))
                from
                true)]
     (do
       (async/<!! work)
       (async/<!!
         (async/reduce + 0 to)))))
Evaluation count : 42 in 6 samples of 7 calls.
            Execution time mean : 15,824584 ms
   Execution time std-deviation : 189,562450 µs
  Execution time lower quantile : 15,691798 ms ( 2,5%)
  Execution time upper quantile : 16,145688 ms (97,5%)
                  Overhead used : 1,808581 ns

Found 1 outliers in 6 samples (16,6667 %)
 low-severe   1 (16,6667 %)
Variance from outliers : 13,8889 % Variance is moderately inflated by outliers
=> nil
впрочем, то же самое делается проще с pmap
(criterium/quick-bench
   (reduce + (let [limit (int 1e8)
                   parallelism 100
                   chunk-size (int (/ limit parallelism))]
               (pmap (fn [_]
                       (loop [i (int 0)
                              n (int chunk-size)]
                         (if (pos? n)
                           (recur (unchecked-inc i) (unchecked-dec n))
                           i)))
                 (range parallelism)))))
Evaluation count : 42 in 6 samples of 7 calls.
            Execution time mean : 15,587236 ms
   Execution time std-deviation : 253,629665 µs
  Execution time lower quantile : 15,394598 ms ( 2,5%)
  Execution time upper quantile : 16,013861 ms (97,5%)
                  Overhead used : 1,808581 ns

Found 1 outliers in 6 samples (16,6667 %)
 low-severe   1 (16,6667 %)
Variance from outliers : 13,8889 % Variance is moderately inflated by outliers
=> nil
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Sergey Trofimov
в кложе для такого reducers придуманы
а так пробовать надо
с редюсерами не удалось получить быстрый расчёт с распараллеливанием

(time
   (let [limit (int 1e8)
         parallelism 100
         chunk-size (int (/ limit parallelism))
         coll (vec (repeat limit 1))]
     (time
       (r/fold chunk-size
         (fn
           ([] 0)
           ([i x] (+ i x)))
         (fn
           ([] 0)
           ([i _] (unchecked-inc i)))
         coll))))
"Elapsed time: 1337.647 msecs"
"Elapsed time: 2510.5126 msecs"
=> 100000000
источник

DF

Dima Fomin in Clojure — русскоговорящее сообщество
Sergey Trofimov
ускорение в 4 раза по сравнению с инкрементом в один проход
О! Класс, спасибо! Вобщем вывод ясен - мутейтить общий стейт - тормозно, лучше всего в stateless цикле накопить и потом по разу на тред послать результат.
Я вставил цикл в свой кусок с Adder и тоже получилось, как с async по времени
источник

DF

Dima Fomin in Clojure — русскоговорящее сообщество
В будни проверю на рабочей тачке, какая картина будет с 99 ядрами :)
источник
2020 January 12

A

Aleksey @cheatex in Clojure — русскоговорящее сообщество
Dima Fomin
О! Класс, спасибо! Вобщем вывод ясен - мутейтить общий стейт - тормозно, лучше всего в stateless цикле накопить и потом по разу на тред послать результат.
Я вставил цикл в свой кусок с Adder и тоже получилось, как с async по времени
А без вложенного цикла сильно хуже?
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Dima Fomin
О! Класс, спасибо! Вобщем вывод ясен - мутейтить общий стейт - тормозно, лучше всего в stateless цикле накопить и потом по разу на тред послать результат.
Я вставил цикл в свой кусок с Adder и тоже получилось, как с async по времени
async и pmap без использования искусственно введённых range или repeat, как в примерах выше

(criterium/quick-bench
   (let [limit (int 1e8)
         parallelism 100
         chunk-size (int (/ limit parallelism))
         from (async/to-chan
                (repeat parallelism (fn []
                                      (loop [i (int 0)
                                             n (int chunk-size)]
                                        (if (pos? n)
                                          (recur (unchecked-inc i) (unchecked-dec n))
                                          i)))))
         to (async/chan parallelism)
         work (async/pipeline parallelism to (map #(%)) from true)]
     
     (async/<!! work)
     (async/<!!
       (async/reduce + 0 to))))
Evaluation count : 60 in 6 samples of 10 calls.
            Execution time mean : 10,729943 ms
   Execution time std-deviation : 141,940603 µs
  Execution time lower quantile : 10,572088 ms ( 2,5%)
  Execution time upper quantile : 10,929712 ms (97,5%)
                  Overhead used : 1,827556 ns
=> nil
(criterium/quick-bench
   (reduce + (let [limit (int 1e8)
                   parallelism 100
                   chunk-size (int (/ limit parallelism))]
               (pmap #(%)
                 (repeat parallelism (fn []
                                       (loop [i (int 0)
                                              n (int chunk-size)]
                                         (if (pos? n)
                                           (recur (unchecked-inc i) (unchecked-dec n))
                                           i))))))))
Evaluation count : 60 in 6 samples of 10 calls.
            Execution time mean : 10,509147 ms
   Execution time std-deviation : 113,948602 µs
  Execution time lower quantile : 10,376058 ms ( 2,5%)
  Execution time upper quantile : 10,631008 ms (97,5%)
                  Overhead used : 1,827556 ns
=> nil
источник

IP

Ilya Pomaskin in Clojure — русскоговорящее сообщество
Там профунктор оптикс собирается провести онлайн хакатон: https://t.me/libmustdie/3849
Кто-нибудь от clojure-сообщества будет участвовать?
Telegram
∏ρ؃uñçτØρ Øπτµç∑ | 👁‍🗨››››
ХАКАТОН ПРОФУНКТОРА 17-19 ЯНВАРЯ

Словарь определений:
Команда — от 1 до 5 человек пилящих один проект, из них один капитан
Капитан — автор идеи, презентует проект на демо
Чекпоинт — команда сабмитит текущий прогресс судьям
Судьи —  админы профунктора
Проект — что угодно что можно задеплоить или по тегам: telegram, memes, profunctor api, ML, dev tools, whatever

Формат:
17-ого (ПТ) в 21-00 МСК дедлайн заявок команд, LIVE где пересчитываем тимы и стартуем
18-ого (СБ) в 15-00 МСК первый чекпоинт
19-ого (ВС) в 12-00 МСК второй чекпоинт
19-ого в 20-00 Финиш, LIVE где капитаны презентуют проекты
22-ого  судьи совещаются и объявляют победителей

Как подать заявку (идею) ?
пишите в чат https://t.me/joinchat/DWka6hBjhmayFl3g0_wv9A в формате:
1. описание в одном предложении
2. ссылка на гист с подробным описанием (стэк, репа, пэйперы и тд)
3. свой контакт

и меншните @olegakbarov

Где?
Все онлайн и ремоут. Команды сами координируют действия и пользуются удобными тулами.

Как найти проект/команду?
Зайти в чат и выбрать…
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Dima Fomin
В будни проверю на рабочей тачке, какая картина будет с 99 ядрами :)
дальше нужно двигаться в этом направлении 😊
https://clojurecuda.uncomplicate.org/
источник

DF

Dima Fomin in Clojure — русскоговорящее сообщество
вау, не знал, что CUDA уже и до кложи добралась, надо будет заценить :) Но там поди специфические области применения - матрицы и все такое.
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
ну, ты же какие-то вычисления собираешься на ядрах проводить 😊
источник