Mutex Vs Spinlock

1.
어플리케이션에서 레이턴시를 줄이는 일은 그리 간단하지 않습니다. 예를 들어 Multi-Threaded Trading Application을 구현할 때 Lock-free Algorithm을 사용하는 경우가 많다고 하였습니다.

전략의 복수이벤트처리

그렇지만 Lock-Free Algorithm이 전가의 보도(傳家寶刀)처럼 Latency를 확 줄여주지 않습니다. 반대로 많은 프로그램들은 쓰레드동기화를 위하여 Lock을 사용합니다. 대표적인 방법은 Mutex입니다. Mutex를 사용한다고 해서 무조건 느린 어플리케이션이라고 할 수도 없습니다. 목표로 하는 업무와 하드웨어환경에 따라 최적화한 방법을 꾸준히 찾아내는 것외엔 방법이 없습니다. 지루한 작업입니다.

앞서 Mutex를 이야기했지만 Mutex이외에도 여라가지 Lock이 있습니다. 그중 하나가 SpinLock입니다.

Multithread, multiprocessor 환경에서는 여러 thread에서 동시에 하나의 resource에 접근해서 이 resource의 값을 바꾸는 시나리오가 생길 수 있다. 예를 들자면 두 개의 thread가 전역(global) 변수의 값을 동시에 바꾸려고 할 경우. 이 때 값을 바꾸는 기계어코드(Assembly code)가 atomic instruction(atomic instruction:이 instruction이 실행되고 있을 때 context switching이 일어나지 않는 것을 보장한다.) 이 아니기 때문에 변수의 값이 망가질(corrupted) 수 있다.

이 때 한 번에 한 thread만이 변수(resource)에 쓸 수 있도록 보장하는 것이 spinlock과 mutex이다. 즉 변수에 접근하기 전에 spinlock이나 mutex를 얻고 변수의 값을 바꾸고 나서는 spinlock 또는 mutex를 반환하는 것이다. 한 thread (A)가 mutex를 얻고자 할 때 다른 thread (B)가 이미 그 mutex를 가지고 있다면 일반적으로 OS scheduler는 그 thread (A)를 suspend 시키고 mutex가 release되었을 때 thread A를 다시 scheduling한다. 같은 시나리오에서 spinlock을 얻고자 하는 thread는 spinlock이 릴리즈되었는지 체크하면서 suspend되지 않는다.

resource가 빨리 릴리즈되어 spinlock으로 낭비되는 CPU time이 context switching으로 인한 latency보다 작다면 spinlock의 사용을 생각해 볼 수 있다. Single Processor환경에서 spinlock의 사용은 의미가 없으며 deadlock을 일으킬 수도 있다. 한 thread에서 recursive하게 같은 spinlock을 얻고자 하는 경우에도 deadlock이 발생 할 수 있다. 반면에 Mutex는 recursive하게 얻을 수 있다.
Spinlock과 Mutex (1)중에서

그러면 Lock을 이용한 다양한 방법중 어떤 것이 가장 좋을까요? 이곳저곳에서 조사한 자료들입니다.
먼저?Ivan Novick(Engineer at Greenplum Divsion of EMC)가 공개한 multi-threaded concurrency syncronization performance testing을 위한 프로그램입니다.

개발서버에서 실행한 결과입니다. 참고로 Quadcore입니다.

같은 소스를 최적화옵션을 주고 컴파일을 한 후 실행해보았습니다.

Spin Lock의 경우 CPU 코어에 비해 Thread가 너무 많을 경우 성능이 떨어지는 듯 합니다. 다음은?pthread mutex vs pthread spinlock에 올라온 프로그램입니다.

 

역시 개발서버에서 실험한 결과입니다.

Spinlock이 Mutex에 비해 3배정도 좋은 듯 합니다.

2.
또다른 자료입니다. 리눅스환경이 아닌 Sparc Solaris입니다. The cost of mutexes에 올라온 자료입니다.

제가 Sparc CPU를 사용하는 서버가 없어서 시험을 하지 못했습니다. 저자가 올려놓은 결과는 이렇습니다.

이렇게 해석합니다.

So the mutex calls are about 3x slower than atomic operations. Calling libc is about 10ns slower than using an inline template (not a bad difference in return for not having to write the inline template code).

오라클의 수석엔지니어는 Inline을 이용한 방법이 최선이라고 주장합니다. 그래서 아래와 같은 글도 썼네요.

Using Inline Templates to Improve Application Performance

3.
다양한 방법에 대한 결과들입니다. 위의 소스를 이용하여 목적에 맞도록 수정하여 Performance를 점검해보시면 개발할 때 도움이 되리라 생각합니다. 그렇다고 ‘한방’을 기대하지 마시길 바랍니다.

오히려 끊임없이 진화하는 프로그램이도록 노력하는 것이 현명할 듯 합니다. 그래서 저의 목표는 지속적인 버전업(Version Up)입니다.

Leave a Comment

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.