Привязка определенных потоков к определенным ядрам процессора

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

меня в основном интересует c++, но я сделал некоторое кодирование этого на Java, поэтому эти ответы также приветствуются.

3 ответов


я отвечаю в перспективе Java: это невозможно. Лучшее, что вы можете контролировать-это приоритета потока. Чтобы заставить Java работать на определенном CPU / core, вы должны сделать это определенным образом. В Windows например, вы можете сделать это в диспетчере задач найти процесс в процессы tab, rightclicking рассматриваемый процесс (обычно java.exe), выберите Задать Сходство и отметьте CPU/Core.

enter image description here

Как вы можете догадаться, это действительно глобально устанавливает сродство, а не на основе потоков, которые вы создаете в Java.


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

наивное, но все более отвергаемое представление заключается в том, что увеличение потоков (в пределах разумного) увеличивает пропускную способность для таких систем. Тем не менее, доказательства того, что при правильном проектировании, решения, которые используют очень мало потоков для большинства обработки, вероятно, значительно превзойдут решения с высоким параллелизмом-иногда в десять или даже в сто раз.

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

Если вы хотите минимизировать переключение контекста, где низкая латентность имеет первостепенное значение, некоторые критические процессы могут быть лучше всего ограничены одним ядром или потоком ЦП. Если необходимо, чтобы несколько потоков считывали или записывали данные, управляемые этими критическими процессами с ограниченным потоком, вы можете посмотреть шаблон "Disruptor", который использует кольцевой буфер плюс количество умных трюков, позволяющих очень быстрый доступ к общим данным, в то время как вряд ли когда-либо требуется эксклюзивная блокировка этих данных (см. ниже).

для достижения задач сродства потоков (привязки ЦП) независимым от ОС способом в Java вы можете использовать библиотеку сродства потоков Java Питера Лоури, также связанную ниже. Также отметьте пример, в котором Петр привязывает читателя нить один гипер-нить гипер-резьбовой стержень, и писатель-нить другой трюк, который я мог представить имея ощутимые преимущества (хотя я не пробовал).

Барни

http://lmax-exchange.github.io/disruptor/

https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/How-it-works


в Windows вы можете использовать SetThreadAffinityMask задать соответствие процессоров для потока.