Я много осмотрелся и не могу найти то, что искал, но позвольте мне сначала подчеркнуть, что я не ищу высокоточную функцию сна.
Вот фон для проблемы, которую я пытаюсь решить:
Я сделал библиотеку отображения памяти, которая работает так же, как именованный канал. Вы можете поместить в него байты, извлечь из него байты и запросить, сколько байтов доступно для чтения / записи, и все такое.
Это быстрые (в основном) процессы, обменивающиеся данными с использованием этого, в среднем будут 4 ГБ / с, если они передают куски байтов 8 КБ или больше. Производительность снижается примерно до 300 МБ / с, когда вы приближаетесь к размеру блока 512B.
Эта проблема:
Время от времени на сильно загруженных серверах происходит очень большое время задержки (более 5 с). Моя теория выполнения для причины этой проблемы состоит в том, что, когда происходят большие передачи (больше, чем размер отображаемой памяти), процесс, который записывает данные, будет тщательно опрашивать, ожидая, когда в циклическом буфере, который реализован, будет доступно больше места. поверх карты памяти. Нет вызовов в спящий режим, поэтому процесс опроса может приводить к перегрузке ЦП без веской причины! Проблема в том, что даже самый маленький вызов в спящий режим (1 мс) абсолютно разрушит производительность. Размер memmap составляет 16 КБ, поэтому, если он спит по 1 мс каждые 16 КБ, производительность упадет до наилучшего сценария 16 МБ / с.
Решение:
Мне нужна функция, которую я могу вызвать, которая освобождает процессор, но не накладывает никаких ограничений на то, когда он будет перенесен операционной системой (в данном случае Windows 7).
У кого-нибудь есть какие-нибудь яркие альтернативы? / Кто-нибудь знает, существует ли такая функция?
Благодарю.
Согласно документации MSDN, на XP или новее, когда вы звоните Sleep
с таймаутом 0 уступит другим процессам с равным приоритетом.
Нулевое значение заставляет поток отказаться от оставшейся части его
отрезок времени для любого другого потока с равным приоритетом, который готов к
запустить. Если нет других потоков с равным приоритетом, готовых к запуску,
Функция немедленно возвращается, и поток продолжает выполнение.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx
Другим вариантом, который потребует больше работы, но который будет работать более надежно, будет разделение дескриптора события между процессом производителя и потребителя. Ты можешь использовать CreateEvent
создать ваше событие и DuplicateHandle
чтобы включить его в другой процесс. Когда производитель заполняет буфер, он будет вызывать ResetEvent
на дескриптор события и вызов WaitForSingleObject
с этим. Когда потребитель удалит некоторые данные из полного общего буфера, он вызовет SetEvent
, который разбудит производителя, который ждал в WaitForSingleObject
,
std::this_thread::yield()
вероятно, делает то, что вы хотите. Я считаю, что это просто звонки Спать с 0 в большинстве реализаций.
Вам нужно SwitchToThread()
функция (которая будет только оставьте свой временной интервал, если что-то еще может работать), не Sleep(0)
(который было бы отказаться от своего временного интервала, даже если больше ничего не может работать).
Если вы пишете код, предназначенный для использования гиперпоточности, YieldProcessor
может тоже что-то сделать для вас, но я сомневаюсь, что это будет полезно.
Вы неправильно предполагаете бинарный выбор. Теперь вы всегда заняты ожиданием, потому что спать всегда было бы плохой идеей.
Лучшее решение — попробовать несколько раз без сна. Если это по-прежнему не удается (поскольку карта заполнена, а другой поток не запущен), вы можете выполнить настоящий сон. Это будет достаточно редко, что в среднем Вы будете спать микросекунды. Вы могли бы даже проверить часы реального времени (RDTSC
) чтобы определить, сколько времени вы потратили на ожидание, прежде чем сдать свой временной график.
Если вы работаете в .Net, вы можете посмотреть в Thread::Yield()
метод.
Это может или не может помочь с вашим конкретным сценарием, но это правильный способ уведомить планировщик, что вы хотите отказаться от оставшейся части вашего временного интервала.
Если вы работаете в среде, предшествующей .Net (кажется маловероятным, если вы работаете в Windows 7), вы можете заглянуть в Win32 SwitchToThread()
функция вместо