Где-то в 2017 году при отладке в VS производительность в проекте упала на ~80%, превратив игру в набор различных асинхронных кадров.
Виновником торжества стала функция SetThreadName внутри пула.
Для тех, кто незнаком, ThreadPool — это своего рода менеджер, отвечающий за параллельное выполнение одного и того же кода.
Например, вот так можно распределять циклы.
Суть его в том, чтобы создать несколько потоков (по 1 рабочему на каждое ядро) и перевести их в режим ожидания/удаление по завершении работы.
SetThreadName выглядел так:
В новом WinSDK старый добрый хак с RaiseException можно заменить на SetThreadDescription , что в конечном итоге спасает ситуацию.void SetThreadName(DWORD dwThreadID, const char* threadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = threadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; #pragma warning(push) #pragma warning(disable: 6320 6322) __try{ RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); } __except (EXCEPTION_EXECUTE_HANDLER){ } #pragma warning(pop) }
Потому что RaiseException — довольно медленная операция.
Оптимальных выходов из ситуации было несколько:
- Ни в коем случае не называйте имена работников.
- Давай только при инициализации и сохраняй треды в режиме ожидания.
Этот метод плох при присоединении к работающему процессу — мы уже не распознаём имена.
- Рабочие не уничтожаются.
Каждая задача проверяется на наличие подключенного отладчика, если он был ранее отключен.
IsDebuggerPresent
-
Почему Стоит Покупать Дешевые Планшеты?
19 Oct, 24 -
Cjm Для Ложных Срабатываний Антивируса Drweb
19 Oct, 24 -
Латексные Вычисления? Да Легко!
19 Oct, 24 -
Ваш Уровень Программирования И Многое Другое
19 Oct, 24