Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

12.03.2024

Паралелізація 1BRC на Ruby: несподівані результати

Останнє, що я хотів спробувати після минулих експериментів, це паралелізувати розвʼязок, проілюструвати, що це набагато простіше, ніж оптимізувати, та закрити питання. Вийшло трохи не так.

Про паралелізацію. Вочевидь, ми повинні розбити файл на декілька розділів та обробляти їх паралельно, а наприкінці обʼєднати результати. Обʼєднати нескладно, але з розбиттям виникає нюанс: потрібно зробити так, щоб кожний розділ починався з нового рядка.

Зробив так: розділяю розмір файлу на рівні частини, а потім на початку кожної частини зчитую до початку наступного рядка те, що насправді є останнім рядком попереднього розділу. Тому підготовка розділів відбувається з кінця на початок. (Та, може, потрібно додати, що для паралельного читання ми відкриваємо файл окремо для кожного розділу.)

Я знаю три способи технічної реалізації: потоки (Thread), рактори (Ractor) та процеси (fork). Очікування були, що потоки будуть трошечки швидше, а рактори та процеси дадуть близьке до кратного пришвидшення.

Вийшло не так. Потоки вийшли у 8 разів повільніше послідовного обчислення, а рактори та процеси — десь у 5 разів повільніше. Оце диво! Невже паралельне читання з файлу настільки обмежує? Бо я інакше взагалі не розумію, як паралельні обчислення, які помітно навантажують процесор, можуть бути настільки повільними. Поки залишу з тим висновком, що паралелізація теж не магічна та може навіть в рази уповільнити код.

Код тут. Відрізняється тільки манера запуску та збору результатів.