[Concurrency] Compare And Swap (CAS)

compare and swap์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์“ฐ๊ธฐ ์ž‘์—…์— ์‚ฌ์šฉ๋˜๋Š” ์ฃผ์š” ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋‹ค.

lock ์—†์ด ํšจ์œจ์ ์œผ๋กœ ๋ณ‘๋ ฌ ์ž‘์—…์„ ๋™๊ธฐํ™”ํ• ์ˆ˜ ์žˆ์–ด์„œ lock-free operation์ด๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค.



๋ฌธ์ œ

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ํ™˜๊ฒฝ๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
integer ๋ณ€์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋‘๊ณ  ๋™์‹œ์— +1๋ฅผ ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ data race๋กœ ์ธํ•œ ์“ฐ๊ธฐ ์ถฉ๋Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๋‹จ์ˆœ ์“ฐ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์ฝ๊ธฐ-์“ฐ๊ธฐ๊ฐ€ ์ข…ํ•ฉ์ ์œผ๋กœ ์ด๋ค„์ง€๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ๋ฌธ์ œ๋Š” ๋‹น์—ฐํžˆ ๋” ์ปค์งˆ ๊ฒƒ์ด๋‹ค.




Compare And Swap

Compare And Swap, ์ดํ•˜ CAS๋Š” ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ Atomic Operation์ด๋‹ค.
ํ•˜๋“œ์›จ์–ด ์ง€์›์ด๊ธฐ ๋•Œ๋ฌธ์— ์™„์ „ํ•œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

๋ฐฉ๋ฒ•๋ก ์€ ๊ฐ„๋‹จํ•˜๋‹ค. ํŠน์ • ๋ณ€์ˆ˜๋ฅผ ๋‚ด๊ฐ€ ๋“ค์–ด์žˆ์„๊ฑฐ๋ผ ์˜ˆ์ƒํ•œ ๊ฐ’๊ณผ ๋Œ€์กฐํ•ด์„œ, ๊ฐ™์œผ๋ฉด ์“ฐ๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋‹ค๋ฅด๋ฉด ์“ฐ๊ธฐ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
๋ง ๊ทธ๋Œ€๋กœ ๋น„๊ตํ•ด์„œ(compare) & ๋ฐ”๊ฟ”์น˜๋Š”(swap) ๊ฒƒ์ด๋‹ค.

์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ๋‹ค. ์–ธ์–ด๋Š” Rust๋‹ค.

์ด๊ฑด ๊ธฐ์กด ๊ฐ’์— 1์„ ๋”ํ•˜๋Š” ์ •๋ง ๋‹จ์ˆœํ•œ ์ฝ”๋“œ๋‹ค.
ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋„ ๋™์‹œ์„ฑ ํ™˜๊ฒฝ์— ๋งž์ถฐ์ง„ ์—ฐ์‚ฐ์ด๋ผ ์ง„์งœ ๋‹จ์ˆœํ•˜์ง„ ์•Š๋‹ค. ๋ถ€๊ฐ€์ ์ธ ๋…ผ๋ฆฌ๊ฐ€ ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

์ € ์ฝ”๋“œ๋Š” current ๊ฐ’์ด 4์ธ ์ƒํƒœ์˜€๋‹ค๋ฉด (4=>5)๋กœ CAS๋ฅผ ๋‚ ๋ฆฌ๊ฒŒ ๋œ๋‹ค.
์—ฌ๊ธฐ์„œ CAS๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์ด ์ง„์งœ 4๊ฐ€ ๋งž์•˜๋‹ค๋ฉด, CAS ์—ฐ์‚ฐ์€ ์„ฑ๊ณตํ•œ๋‹ค.
ํ•˜์ง€๋งŒ CAS๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์—, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ € ๊ฐ’์„ 100์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค๋ฉด, (4!=100)์ด๋ฏ€๋กœ CAS ์—ฐ์‚ฐ์ด ์‹คํŒจํ•œ๋‹ค.

์ด๋Ÿฐ ์‹คํŒจ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋Œ€๋ถ€๋ถ„์˜ CAS ๊ธฐ๋ฐ˜ ์ฝ”๋“œ๋Š” ์‹คํŒจ-์žฌ์‹œ๋„๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” spin loop ๋กœ์ง์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

CAS ์—ฐ์‚ฐ ๊ฐ๊ฐ์€ ๋‹จ์ผ ์ธ์ŠคํŠธ๋Ÿญ์…˜์ด๋ผ ๋ฆฌ์†Œ์Šค๊ฐ€ ๊ทธ๋‹ค์ง€ ํฌ์ง„ ์•Š์ง€๋งŒ, ์˜ค๋žซ๋™์•ˆ ๋Œ๋‹ค๋ณด๋ฉด CPU ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŽ์ด ๊ฐ‰์•„๋จน๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์“ฐ๋”๋ผ๋„ ์ž˜ ์จ์•ผํ•œ๋‹ค.




CPU ์ธ์ŠคํŠธ๋Ÿญ์…˜

CAS๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ์‹ค์ œ๋กœ CPU ์ธ์ŠคํŠธ๋Ÿญ์…˜ ์ˆ˜์ค€์—์„œ ์ง€์›๋˜๋Š” ๋ช…๋ น์ด๋‹ค. ์ด๋Ÿฐ ์ง„์ •ํ•œ ์›์ž์„ฑ์€ ํ•˜๋“œ์›จ์–ด ์ง€์› ์—†์ด๋Š” ์• ๋‹น์ดˆ ๋‹ฌ์„ฑ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์ธ ์ปดํ“จํŒ… ํ™˜๊ฒฝ์ด ์•„๋‹ˆ๋ผ๋ฉด, CAS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธํ…” ๊ณ„์—ด ํ”„๋กœ์„ธ์„œ์—์„œ๋Š” ์ด ์ž‘์—… ์ž์ฒด๊ฐ€ ํ•˜๋‚˜์˜ ์ธ์ŠคํŠธ๋Ÿญ์…˜์œผ๋กœ ์ œ๊ณต์ด ๋œ๋‹ค. ์ด๋ฆ„์€ cmpxchg์ด๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์ฝ”๋“œ๋Š” rust์˜ ํ‘œ์ค€ ํ•จ์ˆ˜๋ฅผ ์ปดํŒŒ์ผํ•œ ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ๋‹ค.

l์ด ๋ถ™์–ด์„œ ํ”ผ์—ฐ์‚ฐ์ž ์ˆœ์„œ๊ฐ€ ๋ฐ˜๋Œ€๊ธด ํ•œ๋ฐ,
cmpxchgl [์ƒˆ ๊ฐ’] [์ €์žฅ์œ„์น˜]
cmpxchg [์ €์žฅ์œ„์น˜] [์ƒˆ ๊ฐ’]
์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.

๋น„๊ตํ•  ๊ธฐ์กด ๊ฐ’์€ rax, eax, ๋˜๋Š” ax, al ๋ ˆ์ง€์Šคํ„ฐ์—์„œ ๊ฐ€์ ธ์˜จ๋‹ค.
๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’๊ณผ ์ €์žฅ์œ„์น˜์˜ ๊ธฐ์กด๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ์ƒˆ ๊ฐ’์„ ๋„ฃ๋Š” ๊ฒƒ์ด๋‹ค.

ARM์˜ ๊ฒฝ์šฐ์—๋„ ์ธ์ŠคํŠธ๋Ÿญ์…˜์„ ๋ฐ”๋กœ ์ง€์›ํ•œ๋‹ค. ์ด๋ฆ„๋„ ๋งค์šฐ ์ง๊ด€์ ์ธ CAS๋‹ค.




Strong CAS vs Week CAS

๊ทผ๋ฐ ์ž˜ ๋ณด๋ฉด, cas๋Š” ํ•œ๊ฐ€์ง€๋งŒ ์žˆ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ 2๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค. week๋ผ๋Š” ๋ฒ„์ „์ด ๋˜ ์กด์žฌํ•˜๋Š”๋ฐ

์ด๊ฑด Rust์—๋งŒ ์žˆ๋Š”๊ฑด ์•„๋‹ˆ๊ณ , C++ ๋“ฑ์—๋„ ์žˆ๋‹ค.

week๋Š” ๋ณด์žฅ ์ˆ˜์ค€์ด ๋‚ฎ์€ CAS ๋ฒ„์ „์ด๋‹ค.
Strong CAS๊ฐ€ ์ „์šฉ ์ธ์ŠคํŠธ๋Ÿญ์…˜์„ ์‚ฌ์šฉํ•ด์„œ ์™„์ „ํ•œ ๋™์ž‘์„ ๋ณด์žฅํ•œ๋‹ค๋ฉด, week CAS๋Š” ์›์ž์„ฑ๊ณผ ๊ด€๋ จ์ด ์—†๋Š” ์ธ์ŠคํŠธ๋Ÿญ์…˜ 2๊ฐœ๋ฅผ ์กฐํ•ฉํ•ด์„œ ๋А์Šจํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

strong CAS๋Š” ์“ฐ๊ธฐ์— ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด ์„ฑ๊ณตํ–ˆ๋‹ค๊ณ  ํ•˜๊ณ , ์‹คํŒจํ–ˆ๋‹ค๋ฉด ์‹คํŒจํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค.
๋ฐ˜๋ฉด week CAS๋Š” ์“ฐ๊ธฐ์— ์„ฑ๊ณตํ–ˆ๋”๋ผ๋„ ์‹คํŒจํ–ˆ๋‹ค๊ณ  ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ ์„ฑ๊ณตํ–ˆ๋‹ค๊ณ  ํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ์„ฑ๊ณตํ•œ ๊ฒƒ์ด๋‹ค.

week CAS๊ฐ€ ์ด๋Ÿฐ ๋А์Šจํ•œ ๋ณด์žฅ์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ์ด๋‹ค. week CAS๋Š” strong CAS์— ๋น„ํ•ด ๊ทผ์†Œํ•˜๊ฒŒ ์‹คํ–‰ ์„ฑ๋Šฅ์ด ์ข‹๋‹ค. ๊ทธ๋ž˜์„œ ๋งˆ์ดํฌ๋กœํ•œ ์ตœ์ ํ™”๋ฅผ ํ• ๋•Œ, ๊ฑฐ์ง“-์‹คํŒจ๊ฐ€ ํ—ˆ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์‚ฌ์šฉํ•˜๊ณค ํ•œ๋‹ค.
week/strong ๊ฐ„์˜ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” CPU ํ”Œ๋žซํผ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค.

arm์˜ ์˜ˆ๋ฅผ ๋“ค๋ฉด strong CAS ์ธ์ŠคํŠธ๋Ÿญ์…˜์€ ๋‹จ์ผ ์ธ์ŠคํŠธ๋Ÿญ์…˜์ด๊ธด ํ•˜์ง€๋งŒ, ์‚ฌ์‹ค ํ•˜๋“œ์›จ์–ด ๋‚ด๋ถ€์—์„œ retry loop๋ฅผ ๋Œ๋ฆฐ๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์— ๋น„ํ•ด์„œ๋Š” ๋งค์šฐ ๋А๋ฆฐ ํŽธ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  arm์˜ week CAS๋Š” LDAXR/STLXR 2๊ฐœ์˜ ์กฐํ•ฉ์œผ๋กœ ๊ตฌํ˜„๋˜๋Š”๋ฐ, ์ด๊ฑด ์‹คํŒจํ•˜๋ฉด retry loop ์—†์ด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ race๊ฐ€ ์‹ฌํ• ์ˆ˜๋ก ์„ฑ๋Šฅ์ด ์ข‹์„ ์ˆ˜ ์žˆ๋‹ค.





Memory Ordering

์œ„์—์„œ CAS ์—ฐ์‚ฐ์„ ํ• ๋•Œ๋งˆ๋‹ค ordering์ด๋ผ๋Š” ๊ฐ’์„ ๋„˜๊ธฐ๋Š” ๊ฒƒ์„ ๋ดค์„ ๊ฒƒ์ด๋‹ค.
์ด๊ฑด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”ํ• ๋•Œ ์ฝ”๋“œ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•  ์ง€์— ๋Œ€ํ•œ ์ตœ์†Œํ•œ์˜ ๋ณด์žฅ์ด๋‹ค.

์ž์„ธํ•œ ๊ฒƒ์€ ๋ณ„๋„ ํฌ์ŠคํŠธ๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.
https://blog.naver.com/sssang97/223356930725




์–ธ์–ด๋ณ„ ๊ตฌํ˜„

์–ธ์–ด ๊ผด์„ ์ œ๋Œ€๋กœ ๊ฐ–์ถ”๊ณ  ์žˆ๋Š” ์–ธ์–ด๋“ค์€ ์ „๋ถ€ Atomic Primitive์˜ ํ˜•ํƒœ๋กœ ์ง€์›์„ ํ•ด์ค€๋‹ค.
์ด๋ฆ„์€ ๋Œ€๋ถ€๋ถ„ compare_and_swap์ด๋‚˜ compare_and_exchange๋‹ค.

Go๋Š” sync/atomic ๋ชจ๋“ˆ์„ ํ†ตํ•ด ์ง€์›ํ•œ๋‹ค.

Java๋„ atomic ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•ด ์ง€์›ํ•œ๋‹ค.

๋‹ท๋„ท์€ CompareExchange

llvm-ir์—์„œ๋„ ์ธ์ŠคํŠธ๋Ÿญ์…˜ ์ˆ˜์ค€์œผ๋กœ ์ œ๊ณต์ด ๋œ๋‹ค.
https://blog.naver.com/sssang97/221688788376




์‘์šฉ

๋™๊ธฐํ™” ๊ด€๋ จ ๊ธฐ์ˆ ์—๋Š” ํ•ญ์ƒ ํ•ต์‹ฌ์ ์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” lock-free ์—ฐ์‚ฐ์ด๋ผ์„œ ๋‚™๊ด€์ ์ธ ๋™์‹œ์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์ฃผ๋กœ ์“ฐ์ด์ง€๋งŒ, ๋น„๊ด€์ ์ธ ๋™์‹œ์„ฑ์„ ๊ตฌํ˜„ํ•  ๋•Œ๋„ ์ง€๋ฐฐ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

์Šคํ•€๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์‰ฝ๊ณ  ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•๋„ bool flag๋ฅผ ๋‘๊ณ  CAS๋กœ ๋ฌดํ•œ๋ฃจํ”„๋ฅผ ๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค.
์•„๋ž˜๋Š” ์Šคํ•€๋ฝ์˜ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„๋ก€๋‹ค.

CAS๋กœ false=>true ์“ฐ๊ธฐ๊ฐ€ ์„ฑ๊ณตํ•œ๋‹ค๋ฉด lock ์ ์œ ์— ์„ฑ๊ณตํ•œ ๊ฒƒ์ด๋‹ˆ ์ฆ‰์‹œ ์ค‘๋‹จํ•œ๋‹ค.
ํ•˜์ง€๋งŒ ์“ฐ๊ธฐ๊ฐ€ ์‹คํŒจํ•œ๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด๋ฏธ ์ ์œ ์— ์„ฑ๊ณตํ•œ ๊ฒƒ์ด๋‹ˆ ๋ฌดํ•œ๋ฃจํ”„๋ฅผ ๋Œ๋ฆฐ๋‹ค.

Mutex๋ฅผ ๋น„๋กฏํ•œ ๋™๊ธฐํ™” primitive๋“ค๋„ ์‚ฌ์‹ค ๊นŒ๋ณด๋ฉด ๋‹ค CAS ๊ธฐ๋ฐ˜์œผ๋กœ User ๋ ˆ๋ฒจ ์Šคํ•€๋ฝ์„ ๊ตฌํ˜„ํ•œ๋‹ค.

CAS๋งŒ ์“ฐ๋Š”๊ฑด ์•„๋‹ˆ๊ณ  ์ด๊ฒƒ์ €๊ฒƒ ๋งŽ์ด ๋ง๋Œ€์ง€๋งŒ, ์—ฌํ•˜ํŠผ.



์ฐธ์กฐ
https://en.m.wikipedia.org/wiki/Compare-and-swap
https://www.felixcloutier.com/x86/cmpxchg
https://developer.arm.com/documentation/dui0801/l/A64-Data-Transfer-Instructions/CASA--CASAL--CAS--CASL--CASAL--CAS--CASL--A64-
https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange.html
https://stackoverflow.com/questions/25199838/understanding-stdatomiccompare-exchange-weak-in-c11