Telegram Web
> номинация "Лучший анонимный канал"

> требует личных данных для оформления заявки

https://mimp.mosreg.ru/pixel

🤡
#prog #article

Fast Enough VMs in Fast Enough Time

Старая (2012 года) статья про применение RPython (языка реализации PyPy) к реализации VM для ЯП с семантикой слишком необычной, чтобы для него подходили существующие VM.

Чем привлекает RPython? Обещанием: напиши интепретатор для своего ЯП и получили JIT-компилятор бесплатно. Как это работает?

Во-первых, RPython, как можно догадаться по названию — подмножество Python, ограниченное достаточно, чтобы быть статически типизированным (с выводом типов btw) и потому гораздо более подходящим для статического анализа. Также RPython можно компилировать в C для получения бесплатного ускорения от существующих компиляторов.

Во-вторых, JIT-компиляция применяется не напрямую: ускорение происходит за счёт JIT-компиляции самого интепретатора, исполняющего RPython-код. Именно, специальные аннотации в исходном коде говорят интерпретатору RPython, какой регион кода нуждается в компиляции. Когда кусок кода исполняется достаточно много раз, он запускается не через скомпилированный через C машинный код, а через специальный трассирующий интепретатор. Он записывает операции, которые реально исполняются во время выполнения итерации. Полученный список операций (в байт-коде) за счёт трассировки является полностью линейным. Этот список затем подвергается оптимизациям, применимым за счёт статического анализа. Так как байт-код достаточно высокоуровневый, оптимизации могут, например, убирать лишние обращения к словарю, а также пары операций list_push и list_pop. Этот оптимизированный список операций затем компилируется через C в машинный код, и последующие вызовы используют уже его вместо интепретации байт-кода.

Разумеется, эти оптимизации корректны только для конкретной итерации оптимизируемого кода и потому зависимы от конкретных значений переменных и об конкретных выборов ветвления потока управления (а ещё от их конкретных типов). Поэтому трассировка включает в себя особые ассерты, которые это проверяют. В случае провала проверки они возвращают управление обратно интепретатору. С другой стороны, статический анализ трассировки может удостовериться, что некоторые из этих ассертов никогда не выстреливают и потому их можно безопасно убрать.

Автор рассматривает эффект от переписывания старой VM для своего ЯП (ранее написанной на C) на RPython. Замеры показывают, что новая реализация заметно обгоняет старую, и за счёт большей высокоуровневости языка в новую реализацию проще вносить изменения, ускоряющие её ещё больше.

Разумеется, RPython не всесилен. По понятным причинам, если ветвления в коде выбираются слишком непредсказуемо (как в бинарном поиске, например), ускорения реально не происходит, поскольку исполнение слишком часто рано переходит из нативного кода обратно в интепретатор. Как из этого следует, один и тот же код, эквивалентный семантически, может очень по разному проявлять себя под JIT. Также оптимизация байт-кода занимает время, и потому RPython прерывает трассировку, если трейс становится слишком длинным. С другой стороны, RPython позволил серьёзно (на пару порядков в некоторых бенчмарков) ускорить VM по сравнению со старой реализацией, и при этом потребовал весьма небольших вложений времени.
Блог*
#prog #article Fast Enough VMs in Fast Enough Time Старая (2012 года) статья про применение RPython (языка реализации PyPy) к реализации VM для ЯП с семантикой слишком необычной, чтобы для него подходили существующие VM. Чем привлекает RPython? Обещанием:…
#prog #python #article

И ещё серия старых (2012 год) статей от разработчика PyPy о том, как можно написать код таким образом, чтобы получить наибольшее преимущество от трассирующего JIT:

Controlling the Tracing of an Interpreter With Hints, Part 1: Controlling the Extent of Tracing

Controlling the Tracing of an Interpreter With Hints, Part 2: Controlling Optimization

Controlling the Tracing of an Interpreter With Hints, Part 3: Putting it All Together — про то, как организовать структуру представления объектов так, чтобы получить выгоду от JIT (ибо наивный подход со словарями методов толком не ускорить)
В СМЫСЛЕ УЖЕ ОКТЯБРЬ
#prog #article

Fast Unorm Conversions

Статья о преобразовании u5 в u8 (как часть преобразования из формата с пятью битами на цветовой канал) и о том, как можно это преобразование ускорить.

Спойлер: по сравнению с наивной версией (с использованием чисел с плавающей точкой) можно ускорить код в 43 раза (и в 46 раз, если написать код, позволяющий задействовать дополнительные возможности по оптимизации автовекторизатора).
#prog #rust #article

Safety Goggles for Alchemists

Или о предстоящих изменениях в язык, которые позволят сделать transmute полностью safe в тех случаях, когда это так (у компилятора есть вся необходимая информация для этого), а в тех случаях, когда это не так — указывать, какие именно небезопасные аспекты проверяет программист, и оставить компилятору проверку остальных аспектов.
Forwarded from Карты, коты, крафт и карандаш
Зимона из Квандрикса настолько алгебраична, что её новая карта впервые в #мтг использует простые числа.
Forwarded from Карты, коты, крафт и карандаш
Блог*
Зимона из Квандрикса настолько алгебраична, что её новая карта впервые в #мтг использует простые числа.
Потом с этой дамочкой сочинили упоротую комбу, уходящую в бесконечность, только если верна нерешённая гипотеза о простых числах-близнецах: https://www.reddit.com/r/BadMtgCombos/comments/1feps3y/deal_infinite_damage_for_4gru_as_long_as_the_twin/
Почти так же эпично, как решение супермутаций, которое однажды запостили на 4chan в аниме-треде (https://www.youtube.com/watch?v=OZzIvl1tbPo)
#мтг
#prog #rust #rustlib

griddle — библиотека, которая реализует hash map с амортизированной по операциям вставки расширением размера. Может быть полезна для случаев, когда важна маленькая tail latency. Реализована не с нуля, а с помощью "сырого" API hashbrown.

На графике бенчмарк операций вставки для HashMap из std и griddle::HashMap.
#prog #python

IceCream — Never use print() to debug again

Или dbg! из Rust в Python.

TL;DR:

from icecream import ic

def foo(i):
return i + 333

ic(foo(123))

Вывод:

ic| foo(123): 456

ic возвращает аргументы:

>>> a = 6
>>> def half(i):
>>> return i / 2
>>> b = half(ic(a))
ic| a: 6
>>> ic(b)
ic| b: 3
Forwarded from Segment@tion fault
Когда долго играл в Rust, иногда вылазит боком
Forwarded from Nero's (Александр Ф. 🇷🇺)
Я сотворил мем
2024/10/05 03:44:50
Back to Top
HTML Embed Code: