Search
Write a publication
Pull to refresh
11
0
Denis Tishkov @DenisT

Разработчик

Send message
Вам тоже спасибо за дополнения и свой опыт
1) Еще нет такой информации, но вообще гипервизор должен давать не существенный оверхед, проблема скорее в том, что железо шарится между несколькими виртуалками
2) В 2 раза не пробовали увеличить и возможности такой пока нет, но мы исходим из того, что при текущем allocation rate = 10 MB/sec, свободных 4-х GB должно хватать. Мы возлагаем надежды на Shenandoah, возможно поможет, если из коробки не поможет, будем тюнить его как сможем
>> почему бы тогда не поднять несколько экземпляров сервиса и не пусть трафик через балансировщик
мы примерно так и делаем, есть несколько одинаковых расчетных сервисов, на уровне нашего клиента (джарника с grpc) принимается решение, к какому инстансу подключиться
Спасибо большое за примеры! Очень полезное дополнение.
>> а вы его обозвали недостатком!
я скорее про сравнение с синхронным кодом:
res1 = calc1()
res2 = calc2()
sendResult(res1 + res2)

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

Я правильно понимаю, что в вашем коде акторы создаются динамически, на разные состояния (во втором примере)? Существенный ли оверхед на это? (мы стараемся акторы динамически не создавать и кешировать их)
Я специально в статье привел пример CalculationActor, т.к. в нем есть код по обработке входящих сообщений в createReceive() и onCalculate, и отправки результата в том же onCalculate методом sender.tell.
Код клиента можно посмотреть здесь — в нем отличие в методе preStart, где планируется отправка сообщений каждые 100 ms (эмулирется нагрузка и непрерывная работа).

>> реактивность от которой отказались, как я понял, именно в угоду читаемости.
я бы сказал, что «не перешли», а не «отказались».
1) На виртуалках, планируем переезд на реальное железо
2) Где-то 16GB живых объектов, в основном это статические данные для расчетов.

Если уточните для каких целей спрашиваете, может быть смогу более развернуто ответить
хорошие новости, спасибо)
  1. Shenandoah очень хотим попробовать, но у нас есть ограничения по версии jdk, которую можем использовать в продакшене, мы пока на 11, как только появится возможность перейти на 14 Java или выше, обязательно попробуем.
    Zgc нет не пробовали.
  2. С GraalVm, в бесплатной версии не оптимально сделано выполнение simd вычислений, что для нас важно, а платную версию не было возможности протестировать.

Кстати, если вам интересна тема ухищрений на Java для высокопроизводительных вычислений, то возможно будет интересен доклад https://youtu.be/QV-ue1YMdds

Я не знаком с Clojure, но мне сложно представить конецепцию проще актора для параллельных вычислений — сообщение на входе — сообщение на выходе:)
>> 6 раз независимо друг от друга
Да, правильно, расчеты независимые. 1,5 ms на один расчет. И мы, конечно же, выполняем эти расчеты параллельно.
>> Для параллельного вычисления изначально и задействовали akka. Так?
Сами расчеты, два вложенных цикла, как раз то место, где akka не используется. Итерации по циклам разбиваются на батчи и обсчитываются параллельно на ForkJoinPool. На выходе получается 0,3 ms вместо 1,5. Почему не akka? Это как раз тот кейс, где акка не очень удобна. Нужно через сообщения выстраивать машину состояний и реагировать в зависимости от посчитанных значений, ForkJoinPool в этом месте удобнее.
>> Или есть какие-то другие веские причины, чтобы использовать akka?
Не очень понял, вопрос относится непосредственно к расчетам или к проекту в целом? Про расчеты написал выше, а про проект, почему акка написано в разделе «Преимущества акторов»
Спасибо за отзыв
1. Конкретно Caffeine явно не используем. В описании к нему написано, что он используется в Akka и Spring. Если так, тогда используем неявно. А вообще, вместо разрозненных кешей мы используем спапшет данных. Снапшет — это уже преобразованные, предагрегированные данные и разложенные по обычным HashMap для быстрого поиска. Снапшет меняется только несколько раз в день, поэтому там достаточно обычных HashMap. Real-time данные раскладываем в ConcurrentHashMap
2. Нет, напрямую off-heap memory не используем. Для экономии на GC используем пулы объектов, про это напишу ниже. Статья как раз о том, что без сильных ухищрений с GC от Java можно получить хорошую производительность. Лично мое мнение, использование напрямую off-heap memory не через фреймворки и библиотеки очень опасно для проекта, начиная с того, что Unsafe рано или поздно задеприкейтят и заканчивая core дампами в продакшене. Если в проекте много мест где хочется использовать Unsafe, тогда, скорее всего, Java не лучший выбор для проекта, возможно стоит рассмотреть связку С/С++ + JNI или вынести высокопроизводительный код в отдельный процесс на том же С/С++.
3. Да используем. В расчетах с матрицами. Каждая строка матрицы это массив и эти массивы переиспользуются в расчетах. Для кеширования используем очередь из JCTools. Потоки берут преаллоцированные массивы из этой очереди и кладут их обратно после завершения вычислений.
4. Скорее особенность скиллсета разработчиков. На скалу переходить не планировали, связка Akka + Java вполне устраивает.

Немного обобщу свои ответы: в нашем проекте мы особо не экономим на аллокациях небольших объектов и позволяем гарбедж коллектору их собирать, кешируем только массивы. Работаем с данными либо через большой снапшет, либо через небольшие кеши поверх ConcurrentHashMap. Не прибегая к особым ухищрениям мы сохраняем для себя удобство разработки на Java, но жертвуем тем, что обслуживание части запросов все-таки выпадает на GC паузы (не больше 5%) и обслуживаются не за 3-4 ms а за 150-200 ms. Для нас это осознанный tradeoff.
обязательно поделимся:)
Нет не сравнивали, хотя идея хорошая, спасибо!

Цифр не хватает, какая разница по скорости на практике получается.

Спасибо за результаты. Подскажите, а чей код в msort.h и rsort.h, Ваш?
Здали вы мне задачку:) Можете скинуть ссылку на примеры описания РАМ или РАСП, которые считаете наиболее удачными?
В статье явно говорится, что для GPU используется Thrust и почему, про STL может быть и не явно, но подразумевается. Суть статьи — как быстро подступиться, т.е. без хардкорного С и CUDA девелопмента. По хорошему, тогда нужно на asm писать под конкретный процессор.
STL, т.к. многие им пользуются (хоть, он и не всегда эффективен) и не все готовы писать код, который приводите Вы. Для GPU я так же не утверждаю, что thrust самая быстрая библиотека.

>> На задаче сортировки это сравнение выглядит особенно «нелепо»
Вы не поняли, в чем суть этих графиков. Я не заявляю, что «GPU крут во всех задачах», я привожу конкретное latency для конкретного подхода. Один CPU поток, т.к. методом не сложных математических вычислений, можно прикинуть, какое latency будет, если алгоритм распарралелить. Для GPU — это примеры, от которых можно отталкиваться. Да, это сравнение «теплого» с «мягким», но вычисленный результат в итоге одинаковый и посчитано затраченное время, от которого можно отталкиваться.

>> утилизирующей «видяху» с TDP 250Вт и ценой $5000.
на консьюмерских картах можно что-то похожее получить, для проверки и написан бенчмарк. Мне самому было любопытно, что можно получить с топовой карты.
1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity