Бинарный семафор с накладными расходами по времени против мьютекса

Я запустил пример программы на C++ на платформе vxWorks, чтобы проверить разницу во времени между мьютексом и двоичным семафором. Приведенная ниже программа является прототипом

SEM ID semMutex;
UINT ITER = 10000;
taskIdOne = TASKSPAWN("t1",TASK_PRIORITY_2,0,8192,0,(FUNCPTR)myMutexMethod,0,0);
taskIdTwo = TASKSPAWN("t2",TASK_PRIORITY_2,0,8192,0,(FUNCPTR)myMutexMethod,0,0);
void myMutexMethod(void)
    {
        int i;
        VKI_PRINTF("I'm  (%s)\n",TASKNAME(0) );
        myMutexTimer.start();
        for (i=0; i < ITER; i++)
        {
            MUTEX_LOCK(semMutex,WAIT_FOREVER); 
            ++global;                     
            MUTEX_UNLOCK(semMutex); 
        } 
        myMutexTimer.stop();
        myMutexTimer.show();
    }

В приведенной выше программе есть конфликт (2 задачи пытаются получить мьютекс). мой таймер напечатал 37,43 мс для вышеуказанной программы. С тем же прототипом программа двоичного семафора занимала всего 2,8 мс. Это понятно, потому что двоичный семафор легкий и не имеет многих функций, таких как мьютекс (инверсия приоритета, владение и т. д.).

Однако я удалил одну задачу и запустил указанную выше программу (без конфликтов). Поскольку конкуренции нет, задача t1 просто получает мьютекс, выполняет критическую секцию и затем освобождает мьютекс. То же самое с бинарным семафором.
Что касается таймингов, мьютекс у меня получился 3,35 мс, а бинарный семафор 4 мс.

Я удивлен, увидев, что мьютекс работает быстрее, чем двоичный семафор, когда нет конкуренции.
Ожидается ли это? или я что-то упускаю?

Любая помощь приветствуется. !


person Wild Widow    schedule 24.02.2014    source источник
comment
Я думаю (но не уверен), что такой способ измерения механизмов синхронизации потоков не даст вам правильных результатов, так как таймер также отслеживает время ожидания мьютекса. И это зависит не только от реализации мьютексов и семафоров, но и от того, как операционная система назначает временные интервалы вашей программе. Это, вероятно, будет отличаться каждый раз, когда вы запускаете его. Сколько раз вы пробовали это и как долго?   -  person Excelcius    schedule 24.02.2014
comment
Я запускал его около 20 раз, и результаты были постоянными. Я запускаю эту программу на бездействующем ядре моего контроллера, чтобы этой задаче не мешали уже запущенные задачи в текущем ядре.   -  person Wild Widow    schedule 24.02.2014
comment
Семафор обычно не считается «легким». Если поток не может получить один блок, он должен заблокироваться при вызове ядра, как мьютекс.   -  person Martin James    schedule 24.02.2014


Ответы (1)


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

Другими словами, вы делаете:

1) semTake(semMutex)
2) ++global;
3) semGive(semMutex) // sem owner flag is not changed
4) sameTake(semMutex) // from same task as previous semTake
...

Затем на шаге 4 semTake видит, что владелец sem == текущему идентификатору задачи (поскольку владелец sem был установлен на шаге 1 и никогда не менялся ни на что другое), поэтому он просто помечает семафор как занятый и быстро выскакивает.

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

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

person Chris Desjardins    schedule 24.02.2014
comment
Крис, ты классный. Очень красивое объяснение. Даже я верю, что происходит то же самое. Он оптимизируется, потому что semOwner всегда один и тот же. Спасибо чувак ! - person Wild Widow; 25.02.2014