То, что вы хотите - это барьер, который блокирует ожидающие потоки, пока все потоки не войдут в барьер_ваит (). В зависимости от реализации потоков, у вас уже может быть барьерный примитив (например, pthread_barrier).
Другой вариант - условное ожидание (cond_wait), которое идеально подходит для вашего варианта запуска.
Для синхронизации вам нужно использовать один из этих примитивов. Как вы определили, синхронизация требует дополнительных затрат: либо увеличивайте рабочую нагрузку, либо меньше синхронизируйте, либо используйте другую схему параллелизма (STM)