멀티코어와 동기화

위 코드는 CAS(&p, 기대값, 새 값)를 사용하여 공유 변수 counter를 2배로 만들고 있다. CAS가 실패하여 루프를 다시 도는 경우는 언제인가?

int old, new;
do {
    old = counter;
    new = old * 2;
} while (!CAS(&counter, old, new));
  1. Acounter의 값이 0일 때
  2. Bold를 읽고 나서 CAS를 실행하기까지의 사이에 다른 스레드가 counter를 바꾸었을 때
  3. Cnew의 값이 old보다 클 때
정답과 해설 보기

정답: B. old를 읽고 나서 CAS를 실행하기까지의 사이에 다른 스레드가 counter를 바꾸었을 때

CAS는 counter가 읽었을 때의 old 그대로라면 새 값을 씁니다. 그 사이에 다른 스레드가 값을 바꾸었다면, 손에 든 new는 오래된 값을 바탕으로 계산한 것이므로 쓰지 않고 실패를 반환합니다. 루프는 최신 값을 다시 읽어 계산을 재시도합니다. 덧셈만이라면 fetch-and-add로 충분하지만, 2배로 만드는 것과 같은 임의의 갱신도 이 형태로 불가분하게 수행할 수 있습니다.

  • A. 0이어도 다른 곳에서 바뀌지 않았다면 성공합니다.
  • B. 맞습니다. 오래된 값을 바탕으로 한 계산을 버리고 재시도합니다.
  • C. 값의 대소는 실패 조건이 아닙니다.
이 분야 연습하기 분야로 돌아가기

멀티코어와 동기화의 다른 문제

  1. RISC-V의 LR/SC(load-reserved/store-conditional)와 같은 명령 쌍에서, SC(조건부 스토어)가 실패하는 경우는 언제인가?
  2. CAS를 사용한 락프리 자료구조에서 문제가 되는 ABA 문제에 대한 설명으로 올바른 것은?
  3. RISC-V의 amoadd.w 명령이나 x86의 lock xadd 명령과 같은 fetch-and-add 명령의 동작으로 올바른 것은?
  4. 스핀락(spinlock)에 대한 설명으로 올바른 것은?
  5. 스핀락이 적합하지 않은 상황으로 가장 적절한 것은?

이 분야의 비교