Вступить в клуб →
сложнаявопросМногопоточность и синхронизация

Счётчики потоков в соседних ячейках массива

Каждый из 8 воркеров считает обработанные пакеты в свою ячейку:

std::array<std::atomic<uint64_t>, 8> counters{};

void worker(int id) {
    while (running) {
        handle_packet();
        counters[id].fetch_add(1, std::memory_order_relaxed);
    }
}

Логических пересечений нет — каждый пишет только в свою ячейку. Но при росте с 1 до 8 потоков общий throughput почти не растёт, а perf показывает всплеск обращений к общей памяти. В чём дело?

  • `memory_order_relaxed` заставляет процессор сбрасывать кэш-линию в память на каждой операции
  • Ложное разделение: соседние счётчики попадают в одну кэш-линию, и запись одного ядра инвалидирует её у остальных
  • `std::atomic<uint64_t>` реализован через глобальный мьютекс библиотеки, поэтому все потоки сериализуются на нём
  • Восемь потоков превышают разумную степень параллелизма, ограничение снимается переходом на пул из 2-4 потоков

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела