Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!20.03.2024
1BRC на Ruby: YJIT, потоки, знову Apple Silicon
В одному з обговорень згадали, що ще в Ruby є YJIT, а я згадав, що попередні вимірювання робив без нього. (YJIT оптимізує код через фіксовану адресацію там, де вона можлива.)
Отже, перевірив, що робить YJIT з найшвидшим з моїх рішень. Прискорення у 20% - з одного боку, до кратних прискорень паралелізації далеко, але з іншого, для зміни в один рядок коду (RubyVM::YJIT.enable
з Ruby 3.3.0) - дуже приємно. Для досягнення такого результату вручну потрібна ретельна оптимізація коду, яка часто ще й ускладнює його читання.
Спробував також зробити розвʼязок з пулом потоків (Thread
); хоч вочевидь це не дасть паралелізму, принаймні можна було б провести з користю час очікування на дані з диску. На жаль, оскільки час читання менше за час обробки, а сам пул має ненульову ціну, то розвʼязок з пулом виходить в кращому випадку не повільніше ніж без пула. Зате навчився синхронізувати виконання потоків, про пізніше можна окремо написати.
Нарешті, так і не вийшло виправити segmentation fault
в моєму розвʼязку з пулом ракторів (Linux, Ruby 3.2.2 та 3.3.0.) Причому як з StringScanner
, так і з StringIO
помилка зʼявлялася, хоча в різних місцях. Це на fly.io; локально ж на Apple M2 як рактори, так і процеси дають прискорення у 2.5 разів при пулі з 8 потоків на 8 ядрах. Треба буде колись детально роздивитись, що ж не так з Apple Silicon; ну добре, повільні ядра — повільні, але хіба не має бути прискорення принаймні в 4+ рази?