Как могла простая загрузка dll привести к 100 загрузке процессора в моем основном приложении?
У меня есть отлично работающая программа, которая подключается к видеокамере (камера IDS uEye) и непрерывно берет с нее кадры и отображает их.
Однако при загрузке определенной dll перед подключением к камере программа работает со 100% загрузкой процессора. Если я загружаю dll после подключения к камере, программа работает нормально.
int main()
{
INT nRet = IS_NO_SUCCESS;
// init camera (open next available camera)
m_hCam = (HIDS)0;
// (A) Uncomment this for 100% CPU load:
// HMODULE handle = LoadLibrary(L"myInnocentDll.dll");
// This is the call to the 3rdparty camera vendor's library:
nRet = is_InitCamera(&m_hCam, 0);
// (B) Uncomment this instead of (A) and the CPU load won't change
// HMODULE handle = LoadLibrary(L"myInnocentDll.dll");
if (nRet == IS_SUCCESS)
{
/*
* Please note: I have removed all lines which are not necessary for the exploit.
* Therefore this is NOT a full example of how to properly initialize an IDS camera!
*/
is_GetSensorInfo(m_hCam, &m_sInfo);
GetMaxImageSize(m_hCam, &m_s32ImageWidth, &m_s32ImageHeight);
m_nColorMode = IS_CM_BGR8_PACKED;// IS_CM_BGRA8_PACKED;
m_nBitsPerPixel = 24; // 32;
nRet |= is_SetColorMode(m_hCam, m_nColorMode);
// allocate image memory.
if (is_AllocImageMem(m_hCam, m_s32ImageWidth, m_s32ImageHeight, m_nBitsPerPixel, &m_pcImageMemory, &m_lMemoryId) != IS_SUCCESS)
{
return 1;
}
else
{
is_SetImageMem(m_hCam, m_pcImageMemory, m_lMemoryId);
}
}
else
{
return 1;
}
std::thread([&]() {
while (true) {
is_FreezeVideo(m_hCam, IS_WAIT);
/*
* Usually, the image memory would now be grabbed via is_GetImageMem().
* but as it is not needed for the exploit, I removed it as well
*/
}
}).detach();
cv::waitKey(0);
}
Независимо от фактически используемого драйвера камеры, каким образом загрузка DLL может изменить ее производительность, занимая 100% всех доступных ядер ЦП? При использовании средств диагностики Visual Studio избыточное время ЦП приписывается "[Внешний вызов] SwitchToThread", а не myInnocentDll.
Загрузка только dll без инициализации камеры не приводит к 100% загрузке процессора.
Сначала я подумал о некоторых статических инициализаторах в myInnocentDll.dll, настраивающих поведение потоковой передачи, но я не нашел ничего, указывающего в этом направлении. Какие аспекты следует искать в коде myInnocentDll.dll?
2 ответа
Вы можете отключить состояние простоя процессора в диспетчере камеры IDS, и тогда минимальная загрузка процессора в планах энергопотребления Windows будет установлена на 100%.
Думаю, об этом стоит здесь упомянуть, даже если вы уже решили свою проблему.
После долгих поисков я нашел ответ, и он одновременно удручающе прост и разочаровывает сам по себе:
Это слабая поддержка OpenMP со стороны Microsoft. Когда я отключил OpenMP в своем проекте, драйвер камеры работает нормально.
Причина, по-видимому, в том, что компилятор Microsoft использует OpenMP с ожиданием занятости, а также есть возможность вручную настроить
OMP_WAIT_POLICY
, но поскольку я все равно не зависел от OpenMP, отключение было для меня самым простым решением.
Я до сих пор не понимаю, почему ЦП поднялся только при использовании камеры, а не при запуске остальной части моего решения, даже если библиотека камеры предварительно создана, и мое отключение / включение компиляции OpenMP не может повлиять на нее.. И я также не понимаю, почему они потрудились сделать исправление для VS2010, но у меня нет реального исправления с VS2019, которое я использую. Но проблема предотвращена.