LINUX.ORG.RU

std::mutex пытались захватить целых 28 мс. Почему так долго?

 


0

1

Первый поток захватывает мьютекс 512 раз подряд, потом спит. Второй просыпается по сигналам из сети 15K раз в секунду, пытается взять мьютекс. Обычно это взятие длится 6000...7000 наносек (6.5 мкс). Но измерялка может сказать иногда 18560639 наносек (18.5 мс!). Чем это объяснить?

Поменял mutex на самодельный CAS на базе std::atomic<uint32_t> - среднее время захвата такого мьютекса стало 66 наносек вместо 6500.

P.S. Убрал текстовые логи. Всё стало летать. Я дебил.

Движок:

struct Task {
    some_t *ptr;
    int code;
};

std::mutex mutex_;
std::queue< Task > queue_;

// для замера времени
inline uint64_t curr_nanosec_monotonic() {
    timespec ts;
    if ( 0 == clock_gettime(CLOCK_MONOTONIC, &ts) ) {
        return ts.tv_sec * 1000000000 + ts.tv_nsec;
    }
    return 0;
}

void put()
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    // да, оно может пойти выделять память
    // хорошо бы это замерить, ага... щас пойду замерю.
    queue_.puch_back( Task() );
}

void get()
{
    auto t1 = curr_nanosec_monotonic();
    std::lock_guard<std::mutex> lock(mutex_);
    auto t2 = curr_nanosec_monotonic();
    
    PRINT("mutex get time ns " << (t2 - t1));
    queue_.pop();
}

Поток 1:

for(;;) {
    
    for( int i = 0; i < 512; ++i ) {
        put();
    }
    usleep( 1000 * 30 ); // 30 ms
}

Поток 2:

for(;;) {
    // ждём событие из сети: их частота 15K в секунду, но неравномерно, а разными пачками. Одно соединение, по которому валятся события. Событие - это TCP-пакет из 5 байт полезной нагрузки.
    epoll_wait(); 
    get();
}



Последнее исправление: hlamotron (всего исправлений: 8)

можно cpu time мерять. Вдруг твои тестовые потоки какой-нибудь другой процесс вытесняет.

urquan
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.