Компилятор Go по умолчанию нацелен на почти 20-летний набор инструкций x86-64. Бинарник запустится на любом чипе, но не использует ничего новее 2003 года. Речь про уровни микроархитектуры: v1 — оригинальный AMD64 с SSE2, v2 добавляет popcnt и SSE4.2, v3 — AVX2, v4 — AVX-512. Автор считает эту лестницу устаревшей: она заморожена около 2020 года, а современные процессоры уже поддерживают кучу расширений, которые v4 не требует. Для реального «выжми всё» нужен v5, а лучше вообще перейти на поканальное определение возможностей CPU.
В Go за это отвечает переменная GOAMD64. По умолчанию стоит v1. Автор взял библиотеку Roaring Bitmaps — это сжатый набор битов, который используют в базах данных и поисковиках. Roaring хранит 32-битные целые числа, разбивая их на чанки по 65 536 значений. Каждый чанк упаковывается в один из трёх контейнеров: массив (для разреженных данных), битовая карта (8 КБ бит) или список интервалов (для последовательностей). Всё упирается в операцию population count (popcount) — подсчёт единичных битов в машинном слове. Она вызывается постоянно.
Автор прогнал бенчмарки на Intel Xeon Gold 6548N (Emerald Rapids) под Go 1.26.2 и Roaring v2.18.2 на всех четырёх уровнях. Самый яркий результат — сам popcount. На v1 компилятор использует софтверную эмуляцию. Переход на v2 включает инструкцию popcnt, и время падает на 43%. Бесплатно, просто смена флага. v3 и v4 ничего не дают — одна инструкция уже оптимальна.
Есть и другие выигрыши. Бенчмарк FromDense строит контейнер из плотной битовой карты: нужно посчитать popcount каждого слова, потом выписать позиции единиц. На v2 прирост 21% (за счёт скалярных popcnt и tzcnt). На v3 (AVX2) компилятор авто-векторизует этот цикл до 256-битных регистров, и выигрыш достигает 38%. v4 снова ничего не даёт. Та же картина с операциями пересечения множеств: IntersectionCardinality на v3 ускоряется на 22%.
Вывод автора: всем стоит использовать хотя бы v2 — бинарник будет работать в любом дата-центре и на не слишком старых ноутбуках. v3 может быть полезна. v4 в тестах Go не помогла — видимо, компилятор с ней пока не дружит. Ну и, конечно, надо запускать свои бенчмарки.