Умышленное создание большего количества потоков, чем процессоров, является стандартной техникой, используемой для использования «резервных циклов», когда поток блокируется в ожидании чего-либо, будь то ввод-вывод, мьютекс или что-то еще, предоставляя некоторую другую полезную работу дляпроцессор, чтобы сделать.
Если ваши потоки делают ввод / вывод, то это сильный конкурент для ускорения: поскольку каждый поток блокирует ожидание ввода / вывода, процессор может запускать другие потоки, покаони тоже блокируют ввод / вывод, надеюсь, к тому времени, когда данные для первого потока будут готовы, и т. д.
Другая возможная причина ускорения заключается в том, что ваши потоки испытывают ложное совместное использование .Если у вас есть два потока, записывающих данные в разные значения в одной и той же строке кэша (например, смежные элементы массива), это блокирует ЦП, а строка кэша передается взад-вперед.Добавляя больше потоков, вы уменьшаете вероятность того, что они работают с соседними элементами, и, таким образом, уменьшаете вероятность ложного обмена.Вы можете легко проверить это, добавив дополнительный отступ к вашим элементам данных, чтобы каждый из них имел размер не менее 64 байтов (типичный размер строки кэша).Если ваш четырехпоточный код ускоряется, это было проблемой.