Можно ли эффективно использовать многопоточность в течение короткого периода времени?

Предположим, у меня есть однопоточный код, который что-то делает в основном потоке, и это занимает около 10-20 мс. Я хотел бы использовать два ядра моего процессора и разделить задачу на два потока, живущих на разных ядрах. Технически я, вероятно, должен возобновить два спящих потока и заставить себя спать, пока они не закончат и снова спать. Ничего страшного, если задача достаточно длинная для выполнения. Но в течение 10-20 мс я подозреваю, что наказание за использование хорошо известных методов синхронизации обойдется мне в большую долю времени. Если я слишком подозрительна и Windows/CPU хорошо справляются с работой, делая все запросы на сон / пробуждение эффективными, то какое наименьшее время имеет смысл разделить, 1 мс, 10 мс, 100 мс?

3 ответа

Многопоточность с использованием существующего пула потоков (существующих спящих потоков) может ускорить работу на 10-20 мс.

Специальные вызовы синхронизации, чтобы разбудить потоки и присоединиться к ним, незначительны, намного меньше, чем 1 мс.

Одна вещь, которую нужно знать, это местность ссылки. Если код, работающий в нескольких потоках, обращается к одной и той же памяти, тогда процессорам придется синхронизировать доступ к памяти, что может снизить реальное улучшение производительности.

Точно так же, если потоки используют общие ресурсы и требуют блокировки или синхронизации других потоков, ожидание этих блокировок приведет к снижению производительности.

Если в этих потоках есть какие-либо операции ввода-вывода, то разбиение их на потоки поможет максимально ускорить его.

Если эта короткая задача не вызывается много раз (то есть в цикле), то нет никакого смысла, потому что в лучшем случае вы сэкономите 10 мс времени обработки даже до того, как учтете переключение задач / запуск / синхронизацию потоков...

Если у вас много задач и ваши рабочие потоки непрерывно берут задачи из общей очереди (как в ExecutorService), накладные расходы на задачу составляют 1,10 микросекунды. Средство Fork/Join является еще более эффективным. Переключение потоков является наиболее дорогостоящим действием, поэтому вместо того, чтобы возобновлять 2 спящих потока и заставлять главный поток ждать, лучше запустить одну задачу в главном потоке и только одну в рабочем потоке.

Другие вопросы по тегам