Что такое компромисс для "оживленного ожидания" против "сна"?

Это расширение моего предыдущего вопроса

Как работает режим блокировки в сокетах unix/linux?

То, что я собираю сейчас из Интернета, все процессы, вызывающие блокирующие вызовы, укладываются в спящий режим, пока планировщик не найдет причины разблокировать его. Причины могут варьироваться от пустого буфера до полного заполнения любого другого условия.

Но может ли это быть эффективным способом в реальном времени, можно сказать, жесткие/твердые приложения реального времени? Поскольку процесс не разблокирован, когда условие разблокирования выполняется верно, а когда планировщик предоставит ему его срез процессора, и условие разблокирования будет истинным.

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

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

Ответ 1

Переход на спящий режим до тех пор, пока планировщик не просыпается, вы будете нормальным/предпочтительным.

Спиннинг (альтернативный способ ожидания, без сна) менее обычен и имеет следующие эффекты:

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

  • Можно прекратить вращаться в тот момент, когда вещь, которую вы ожидаете, происходит (потому что вы постоянно проверяете это событие, и вам не нужно тратить время, которое нужно проснуться, потому что вы уже проснулись)

  • Не вызывает вызовы процессора, необходимые для того, чтобы заснуть и снова проснуться.

Спиннинг может быть более эффективным (меньше всего CPU), чем спать, если длина задержки очень мала (например, если задержка составляет только столько, сколько требуется для выполнения 100 инструкций ЦП).

Ответ 2

A Spin Lock записывает CPU и опрошенный путь ресурса для непрерывной траты ресурсов, в то время как желаемое событие не происходит.

Операция

A Блокировка наиболее важна, если оставить процессор и связанный с ним путь ресурса и установить wait какой-либо формы на ресурс, из которого ожидается желаемое событие.

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

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


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

Ответ 3

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

В противном случае вы можете принудительно cond_wait() ЦП с помощью cond_wait() или cond_wait() ing.

Другой сценарий, который я могу придумать для принудительного переключения контекста, заключается в следующем:

while(condition)
    sleep(0);

Ответ 4

Прежде всего, у вас есть неправильное представление:

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

В вопросе блокировки вызовов

Блокировка вызовов проще - их легко понять, легче разрабатывать, проще отлаживать.

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

Это ускоренная разработка и ремонтопригодность? или масштабируемость.

Ответ 5

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

Компромисс по мне должен находиться между Реактивной способностью Vs Пропускная способность системы.

Отзывчивость - может рассматриваться с двух сторон.

  • по всей реакции системы и
  • индивидуальная или оперативная реакция

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

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

Теперь, чтобы повысить общую отзывчивость системы, мы не можем уменьшить временной срез (мелкое зерно) для планировщика, так как это приведет к слишком большому количеству ресурсов ЦП в коммутаторе контекста. И, таким образом, пропускная способность системы резко снизится. Разумеется, очевидно, что блокирующая модель увеличивает пропускную способность системы, поскольку заблокированные вызовы не потребляют кусочки процессора и передают ее другому/следующему процессу в очереди готовности.

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

Ответ 6

//Адаптированный исходный исходный код ASPI...

    DWORD startStopUnit (HANDLE handle, BOOL bLoEj, BOOL bStart)
    {
       DWORD  dwStatus;
       HANDLE heventSRB;
       SRB_ExecSCSICmd s;





    //here
       heventSRB = CreateEvent (NULL, TRUE, FALSE, NULL);

       memset (&s, 0, sizeof (s));

       s.SRB_Cmd = SC_EXEC_SCSI_CMD;
       s.SRB_HaID = 0;
       s.SRB_Target = 0;
       s.SRB_Lun = 0;
       s.SRB_Flags = SRB_EVENT_NOTIFY;
       s.SRB_SenseLen = SENSE_LEN;
       s.SRB_CDBLen = 6;
       s.SRB_PostProc = (LPVOID) heventSRB;
       s.CDBByte[0] = 0x1B;
       s.CDBByte[4] |= bLoEj ? 0x02 : 0x00;
       s.CDBByte[4] |= bStart ? 0x01 : 0x00;

       ResetEvent (heventSRB);
       dwStatus = SPTISendASPI32Command (handle,(LPSRB) & s);
       if (dwStatus == SS_PENDING)
         {
//and here, don´t know a better way to wait for something to finish without processor cicles
        WaitForSingleObject (heventSRB, DEFWAITLEN);
         }
       CloseHandle (heventSRB);

       if (s.SRB_Status != SS_COMP)
         {
    printf("Erro\n");
        return SS_ERR;
         }

       printf("nao Erro\n");
       return s.SRB_Status;
    }