2

I was trying to measure the latency when a thread calling to wake up a sleeping thread. Since it has been said that many synchronization premitives are developed on top of futex, I am expecting futex are always faster. However, my test was giving opposite result. I wonder if I did anything wrong, or it is actually a fact.

Here's the detail of my test:

  • Process have been set affinity to a particular core
  • time is compared by the number returned from RDTSC() instruction
  • 2 threads are created, in which the waking thread2 have higher FIFO priority

Thread1 is sending signal by unlocking the mutex so the Thread2 is supposed to wake up in next schedule. The sleep(1) on thread1 is to make sure the thread2 sleep waiting for the mutex at the time mutex_unlock is called.

void *Thread1(void *dummy)
{
    while(1)
    {
        pthread_mutex_lock( &mutx );
        sleep(1);
        t1 = rdtsc();
        pthread_mutex_unlock( &mutx );
        pthread_yield();
    }
    return NULL;
}

void *Thread2(void *dummy)
{
    while(1)
    {
        pthread_mutex_lock( &mutx );
        t2 = rdtsc();
        if(t1>0)
        {
                    // print out the result
            cout << t2-t1 << endl;
            t1 = 0;
        }
        pthread_mutex_unlock( &mutx );
        pthread_yield();
    }
    return NULL;
}

A similar test is done by replacing the mutex with a futex system call:

void *Thread1(void *dummy)
{
    while(1)
    {
        sleep(1);
        t1 = rdtsc();
    syscall(SYS_futex, &futx, FUTEX_WAKE, 1);
        pthread_yield();
    }
    return NULL;
}

void *Thread2(void *dummy)
{
    while(1)
    {
        syscall(SYS_futex, &futx, FUTEX_WAIT, 0);
        t2 = rdtsc();
        if(t1>0)
        {
            cout << t2-t1 << endl;
            t1 = 0;
        }
        pthread_yield();
    }
    return NULL;
}

Both the mutx and futx is declared global. On my Core i7 930 machine, with fedora17, the mutex consistently wake faster than futex by 5-10%. The test application was compiled by gcc 4.7 on default setting. Any suggestion? Thanks in advance.

Codeblue
  • 31
  • 3
  • Could you provide complete code, including declarations? – zch Jan 16 '13 at 18:43
  • Did you read http://www.kernel.org/doc/man-pages/online/pages/man7/futex.7.html ? It explains that `futex` syscall is only done on contention.... thanks to specific atomic assembly instructions – Basile Starynkevitch Jan 16 '13 at 18:50

1 Answers1

1

Futex-based implementation of mutex doesn't do syscall for any lock/unlock operation, but only when needed.

When you replace mutex lock/unlock with unconditional futex syscalls, it is necessary slower.

Anton Kovalenko
  • 20,999
  • 2
  • 37
  • 69
  • Thanks. I understand syscall might be not needed in certain situations for mutex lock/unlock operation, but the purpose of my test was focusing on the time needed to wake up a *sleeping* thread. In this case I believe some syscall should be required to ask the kernel to release a thread anyway in mutex implementation. If mutex is really built on top of futex, a syscall for futex_wake is most likely to be used on its unlock operation. – Codeblue Jan 17 '13 at 07:27