Как мне ограничить внешнюю DLL одним процессором? - PullRequest
2 голосов
/ 07 февраля 2009

У меня есть программа, которую я хотел бы запустить только на одном процессоре, чтобы она не занимала слишком много системных ресурсов. Проблема в том, что он делает вызов во внешнюю DLL, которая автоматически использует все доступные ядра ЦП. У меня нет исходного кода для внешней DLL. Как я могу ограничить DLL только одним процессором?

РЕДАКТИРОВАТЬ: Спасибо за помощь, вот код, который я использовал для ограничения до одного процессора (Windows):

// Limit the process to only 1 thread so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
DWORD ProcessAffinityMask;
DWORD SystemAffinityMask;
if(GetProcessAffinityMask(ProcessHandle,&ProcessAffinityMask,&SystemAffinityMask)
    && SystemAffinityMask != 0)
{
    // Limit to 1 thread by masking all but 1 bit of the system affinity mask
    DWORD NewProcessAffinityMask = ((SystemAffinityMask-1) ^ SystemAffinityMask) & SystemAffinityMask;
    SetProcessAffinityMask(ProcessHandle,NewProcessAffinityMask);
}

РЕДАКТИРОВАТЬ: Оказывается, подход Брэннона по установлению приоритета процесса работает даже лучше для того, что я хочу, а именно, чтобы процесс не занимал ресурсы Вот этот код (Windows):

// Make the process low priority so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
SetPriorityClass(ProcessHandle,BELOW_NORMAL_PRIORITY_CLASS);

Ответы [ 6 ]

9 голосов
/ 07 февраля 2009

Вы можете установить сродство процессора вашей программы. Попробуйте функцию SetProcessAffinityMask в Windows или sched_setaffinity в Linux.

5 голосов
/ 07 февраля 2009

Установка привязки процессора - неправильный подход. Пусть ОС обрабатывает планирование.

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

Windows имеет эту встроенную функциональность. Правильное решение для этого - установить базовый приоритет процесса.

Подробнее о SetPriorityClass().

см. http://msdn.microsoft.com/en-us/library/ms686219(VS.85).aspx.

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

1 голос
/ 07 февраля 2009

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

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

0 голосов
/ 07 февраля 2009

Вы не сказали, для какой платформы это. Я собираюсь взять окна здесь.

Создайте дочерний процесс и свяжите его с Объектом задания . Затем вы можете установить сродство процессора для этого объекта задания, чтобы оно включало только одно из доступных ядер ЦП. Дочерний процесс не может изменить маску сходства на что-либо, что не является подмножеством сходства процессора для объекта задания. Кроме того, следует помнить, что не следует устанавливать предел JOB_OBJECT_LIMIT_BREAKAWAY_OK или расширенный предел JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK для задания, иначе дочерний процесс сможет выйти из задания.

Кроме того, вы можете установить приоритет и класс планирования для задания. Возможно, будет достаточно создать дочерний процесс с более низким уровнем приоритета ЦП и / или ввода-вывода?

0 голосов
/ 07 февраля 2009

То есть ваша программа использует один поток, но вы не хотите, чтобы внешняя DLL использовала более одного потока? Вы не имеете большого контроля над тем, что делает внешняя DLL, но некоторые подходы могут быть:

0 голосов
/ 07 февраля 2009

Э-э ... почему? Серьезно, зачем вам ограничивать библиотеку, которая способна дать вам дополнительную производительность таким образом? Вы пытаетесь получить доступ к общему ресурсу или что-то? Можно было бы подумать, что многопоточная библиотека будет в состоянии справиться с этим безопасно.

Если вы о чем-то не упомянули, я не вижу никакой веской причины даже для попытки ограничить многопоточную библиотеку одним потоком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...