C#의 Interlocked와 하드웨어 원자 연산의 이해
멀티스레드 환경에서 공유데이터를 동기화하기 위해 흔히 사용하는 방법은 Lock이다. 하지만 락은 비용이 크고 성능 병목을 일으킬 수 있다. 이 때 사용가능한 더 가벼운 방법이 Interlocked 클래스를 활용한 원자적(Atomic) 연산이다. 이번 글에서는 C#의 Interlocked가 내부적으로 어떤식으로 하드웨어가 제공하는 원자 연산과 연결되는지 컴퓨터 구조 관점에서 알아보겠습니다.
원자적(Atomic) 연산이란?
원자적 연산이란 연산이 수행될때 중간에 중단되지 않고 완벽하게 완료되거나 아예 수행되지 않은 상태만을 허용하는 연산이다. 원자 연산은 하드웨어 수준에서 CPU가 직접 지원하는 명령어로 보통 구현된다. 대표적으로 x86 CPU에서는 LOCK 접두어를 사용한 명령어(예: LOCK INC, LOCK CMPXCHG)로 지원된다.
하드웨어 수준에서의 원자 연산 구현
하드웨어는 캐시 일관성(Cache Coherence) 프로토콜을 이용해 여러코어 간에 메모리 일관성을 보장한다. 예를 들어, x86 시스템에서는 MESI 프로토콜과 같은 캐시 일관성 프로토콜을 통해 캐시 라인의 독점적인 접근권한을 확보한 후 메모리 연산을 수행한다.
원자연산은 보통 다음과 같은 방식으로 하드웨어에서 구현된다.
특정 메모리 영역에 대해 CPU가 독점적인 접근권한을 확보함
연산을 수행하는 동안 해당 메모리 영역에 대한 다른 코어의 접근을 막음
연산 수행 후 변경 사항이 다른 코어에도 전파됨
예를 들어, Intel CPU의 경우 다음 명령어를 통해 원자성을 제공한다.
1 | LOCK INC DWORD PTR [addr] ; addr의 값을 원자적으로 증가 |
여기서 LOCK 접두어는 해당 메모리 주소를 연산 중에 독점적으로 잠그도록 CPU에게 지시한다.
C# Interlocked 클래스와의 연결
.NET 환경에서는 직접 하드웨어 명령어를 사용하기 어렵기 때문에 Interlocked 클래스를 제공하여 추상화된 원자 연산을 지원한다. Interlocked는 내부적으로 시스템 호출이나 CPU 명령어를 직접 호출하여 원자성을 보장한다.
Interlocked의 주요 메서드
1 | Interlocked.Increment(ref int location) |
Interlocked 메서드의 내부 동작
.NET 런타임은 Interlocked 메서드를 호출하면 JIT 컴파일러가 이를 최적화된 원자 CPU 명령어로 변환한다. 예를 들어, 다음 코드가 있을 때:
1 | Interlocked.Increment(ref myValue); |
실제 CPU에서는 다음과 비슷한 어셈블리 코드로 변환된다:
1 | LOCK INC DWORD PTR [myValue] |
이로 인해 해당 연산은 하드웨어 수준의 원자성을 보장받는다.
락(Lock)과 Interlocked의 차이점
Lock 은 소프트웨어 수준의 동기화 방법으로, 경쟁 상태가 발생할 경우 커널 모드 전환, 컨텍스트 스위칭 등의 비용이 발생할 수 있다.
Interlocked 연산은 하드웨어가 직접 지원하는 연산을 활용하므로 커널 모드로의 전환이나 컨텍스트 스위칭의 비용 없이 매우 효율적으로 수행된다.
따라서 Interlocked는 간단한 원자적 연산의 경우 락보다 훨씬 효율적이다.
주의할 점
Interlocked 연산은 단일 연산의 원자성을 보장하지만, 여러 연산이 복합적으로 이루어질 때는 완전한 원자성을 보장하지 않는다. 예를 들어:
1 | Interlocked.Increment(ref count); |
위 두 연산을 별도로 실행하면, 각각의 연산은 원자적이지만 두 연산이 함께 실행되는 동안 다른 스레드가 접근하면 복합 연산 전체의 원자성은 깨질 수 있다.
이 경우는 명시적인 락이나 더 복잡한 원자적 연산을 사용해야 한다.
정리하며
C#의 Interlocked 클래스는 하드웨어가 제공하는 원자적 연산을 효율적으로 활용할 수 있는 강력한 도구이다. 원자 연산을 제대로 이해하고 사용하면 멀티스레드 환경에서 성능 향상과 정확성을 동시에 얻을 수 있다. 하지만 복잡한 연산의 원자성을 보장해야 할 경우에는 명시적인 락이나 더 강력한 동기화 메커니즘을 사용하는 것이 더 적합한다.