ShovelingLife
A Game Programmer
ShovelingLife
전체 방문자
오늘
어제
  • 분류 전체보기 (1067)
    • 그래픽스 (57)
      • 공통 (19)
      • 수학 물리 (22)
      • OpenGL & Vulkan (1)
      • DirectX (14)
    • 게임엔진 (180)
      • Unreal (69)
      • Unity (100)
      • Cocos2D-X (3)
      • 개인 플젝 (8)
    • 코딩테스트 (221)
      • 공통 (7)
      • 프로그래머스 (22)
      • 백준 (162)
      • LeetCode (19)
      • HackerRank (2)
      • 코딩테스트 알고리즘 (8)
    • CS (235)
      • 공통 (21)
      • 네트워크 (44)
      • OS & 하드웨어 (55)
      • 자료구조 & 알고리즘 (98)
      • 디자인패턴 (6)
      • UML (4)
      • 데이터베이스 (7)
    • 프로그래밍 언어 (346)
      • C++ (167)
      • C# (88)
      • Java (9)
      • Python (33)
      • SQL (30)
      • JavaScript (8)
      • React (7)
    • 그 외 (9)
      • Math (5)
      • 일상 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Source Code 좌측 상단에 복사 버튼 추가 완료
  • 언리얼 엔진 C++ 빌드시간 단축 꿀팁
  • 게임 업계 코딩테스트 관련
  • 1인칭 시점으로 써내려가는 글들

인기 글

태그

  • 포인터
  • 배열
  • 알고리즘
  • C++
  • c#
  • 유니티
  • SQL
  • 백준
  • 언리얼
  • 클래스
  • string
  • 티스토리챌린지
  • 함수
  • 프로그래머스
  • 파이썬
  • 오블완
  • 그래픽스
  • C
  • 문자열
  • Unity

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ShovelingLife

A Game Programmer

Atomic 연산, CAS (CompareAndSwap)에 대하여, ABA 문제
CS/OS & 하드웨어

Atomic 연산, CAS (CompareAndSwap)에 대하여, ABA 문제

2025. 2. 16. 23:02

스핀락, 뮤텍스, 세마포어, 모니터 모두 하나의 Thread가 임계 영역을 Lock한 후 작업을 수행하는 절차이지만 synchronized화 하게 되면 한 개의 Thread가 해당 블락을 전체 lock(점유)하기 때문에 다른 Thread는 아무 작업을 하지 못하게 되고 이로 인해서 기다리는 상황이 발생하고 낭비가 심해진다.

그래서 Non-blocking한 방법, Lock-free한 방법으로 동기화 문제를 해결하기 위한 방법이 바로 Atomic 연산이고 이 동작의 핵심 원리는 CAS (Comparre ANd Swam)에 있다.

CAS (CompareAndSwap) 알고리즘이란?

멀티 쓰레드 환경, 멀티 코어 환경에서 각 CPU는 메인 메모리에서 변수값을 참조하는 것이 아닌 각 CPU에서 캐시 영역에서 메모리를 값을 참조하게 된다. 이때, 메인 메모리에 저장된 값과 CPU 캐시에 저장된 값이 다른 경우가 있다. 이를 가시성 문제라고 한다.

이때 사용되는 것이 CAS 알고리즘, 현재 쓰레드에 저장된 값과 메인 메모리에 저장된 값을 비교하여 일치하는 경우 새로운 값으로 교체하고 일치하지 않는다면 실패하고 재시도를 한다. 이렇게 하면 CPU캐시에서 잘못된 값을 참조하는 가시성 문제가 해결된다. 연산의 결과는 쓰기가 제대로 이루어졌는지 나타낸다. 이 연산은 atomic하기 때문에 새로운 값이 최신의 정보임을 보장한다.

 

구현은 다음과 같다. CAS란 특정 메모리 위치의 값이 주어진 값을 비교하여 같으면 새로운 값으로 대체된다.

 int compare_and_swap(int* reg, int oldval, int newval)
{
  int old_reg_val = *reg;
  if (old_reg_val == oldval)
     *reg = newval;
  return old_reg_val;
}

ABA Problem

CAS연산에서 공유 객체에 대한 변화를 감지하지 못할 때 발생하는 현상을 ABA현상이라고 한다.

 

 

쓰레드 1와 쓰레드 2 그리고 쓰레드 3이 있다고 하자.

쓰레드1은 pop연산을 하려 한다. pop을 하려는 쓰레드1 1은 top을 A로 저장하고 next를 B로 저장할 것이다.

그러나 중간에 다른 쓰레드 2가 끼어들고 A랑 B를 둘다 pop을 해버린다. 그런데 다시 쓰레드 3이 중간에 A의 주소를 그대로 Push해버렸다. 그래서 CAS체크를 하면 Fail이 뜨지 않는다. CAS는 주소가 맞다고 감지하고 그럼 이미 pop해서 FreeList에 있는 B가 스택의 Top이 되어버린다. CAS만으로 주소 값을 비교하다보니 일관성을 보장하기 힘들다.

 

이러한 ABA문제의 해결책으로는 double check CAS 이 있다. pop의 Count를 포함한 double check를 통해서

주소값을 CAS해주고, pop한 count 또한 CAS해주면서 일관성을 보장해준다.

CAS(&s->top, top, new_top) && CAS(&->pop_count, pop_count, pop_count+1)

 

https://wannabe-gosu.tistory.com/29

저작자표시 (새창열림)

'CS > OS & 하드웨어' 카테고리의 다른 글

서비스 공격 유형  (0) 2025.04.18
실수의 부동 소수점 저장 방식  (0) 2025.03.23
동적테스트 화이트박스 테스트 검증기준 (WhiteBox Test Coverage)  (0) 2024.10.21
CPU 스케줄링 /SJF SRT  (0) 2024.10.02
CPU 스케줄링 (Scheduling) 개념  (1) 2024.09.24
    'CS/OS & 하드웨어' 카테고리의 다른 글
    • 서비스 공격 유형
    • 실수의 부동 소수점 저장 방식
    • 동적테스트 화이트박스 테스트 검증기준 (WhiteBox Test Coverage)
    • CPU 스케줄링 /SJF SRT
    ShovelingLife
    ShovelingLife
    Main skill stack => Unity C# / Unreal C++ Studying Front / BackEnd, Java Python

    티스토리툴바