1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136 |
- NOTE:
- This is a version of Documentation/memory-barriers.txt translated into Korean.
- This document is maintained by SeongJae Park <sj38.park@gmail.com>.
- If you find any difference between this document and the original file or
- a problem with the translation, please contact the maintainer of this file.
- Please also note that the purpose of this file is to be easier to
- read for non English (read: Korean) speakers and is not intended as
- a fork. So if you have any comments or updates for this file please
- update the original English file first. The English version is
- definitive, and readers should look there if they have any doubt.
- ===================================
- ์ด ๋ฌธ์๋
- Documentation/memory-barriers.txt
- ์ ํ๊ธ ๋ฒ์ญ์
๋๋ค.
- ์ญ์๏ผ ๋ฐ์ฑ์ฌ <sj38.park@gmail.com>
- ===================================
- =========================
- ๋ฆฌ๋
์ค ์ปค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด
- =========================
- ์ ์: David Howells <dhowells@redhat.com>
- Paul E. McKenney <paulmck@linux.vnet.ibm.com>
- Will Deacon <will.deacon@arm.com>
- Peter Zijlstra <peterz@infradead.org>
- ========
- ๋ฉด์ฑ
์กฐํญ
- ========
- ์ด ๋ฌธ์๋ ๋ช
์ธ์๊ฐ ์๋๋๋ค; ์ด ๋ฌธ์๋ ์๋ฒฝํ์ง ์์๋ฐ, ๊ฐ๊ฒฐ์ฑ์ ์ํด ์๋๋
- ๋ถ๋ถ๋ ์๊ณ , ์๋ํ์ง ์์์ง๋ง ์ฌ๋์ ์ํด ์ฐ์๋ค๋ณด๋ ๋ถ์์ ํ ๋ถ๋ถ๋ ์์ต๋๋ค.
- ์ด ๋ฌธ์๋ ๋ฆฌ๋
์ค์์ ์ ๊ณตํ๋ ๋ค์ํ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ ์ฌ์ฉํ๊ธฐ ์ํ
- ์๋ด์์
๋๋ค๋ง, ๋ญ๊ฐ ์ด์ํ๋ค ์ถ์ผ๋ฉด (๊ทธ๋ฐ๊ฒ ๋ง์ ๊ฒ๋๋ค) ์ง๋ฌธ์ ๋ถํ๋๋ฆฝ๋๋ค.
- ๋ค์ ๋งํ์ง๋ง, ์ด ๋ฌธ์๋ ๋ฆฌ๋
์ค๊ฐ ํ๋์จ์ด์ ๊ธฐ๋ํ๋ ์ฌํญ์ ๋ํ ๋ช
์ธ์๊ฐ
- ์๋๋๋ค.
- ์ด ๋ฌธ์์ ๋ชฉ์ ์ ๋๊ฐ์ง์
๋๋ค:
- (1) ์ด๋ค ํน์ ๋ฐฐ๋ฆฌ์ด์ ๋ํด ๊ธฐ๋ํ ์ ์๋ ์ต์ํ์ ๊ธฐ๋ฅ์ ๋ช
์ธํ๊ธฐ ์ํด์,
- ๊ทธ๋ฆฌ๊ณ
- (2) ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐฐ๋ฆฌ์ด๋ค์ ๋ํด ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํ ์๋ด๋ฅผ ์ ๊ณตํ๊ธฐ
- ์ํด์.
- ์ด๋ค ์ํคํ
์ณ๋ ํน์ ํ ๋ฐฐ๋ฆฌ์ด๋ค์ ๋ํด์๋ ์ฌ๊ธฐ์ ์ด์ผ๊ธฐํ๋ ์ต์ํ์
- ์๊ตฌ์ฌํญ๋ค๋ณด๋ค ๋ง์ ๊ธฐ๋ฅ์ ์ ๊ณตํ ์๋ ์์ต๋๋ค๋ง, ์ฌ๊ธฐ์ ์ด์ผ๊ธฐํ๋
- ์๊ตฌ์ฌํญ๋ค์ ์ถฉ์กฑํ์ง ์๋ ์ํคํ
์ณ๊ฐ ์๋ค๋ฉด ๊ทธ ์ํคํ
์ณ๊ฐ ์๋ชป๋ ๊ฒ์ด๋ ์ ์
- ์์๋์๊ธฐ ๋ฐ๋๋๋ค.
- ๋ํ, ํน์ ์ํคํ
์ณ์์ ์ผ๋ถ ๋ฐฐ๋ฆฌ์ด๋ ํด๋น ์ํคํ
์ณ์ ํน์ํ ๋์ ๋ฐฉ์์ผ๋ก ์ธํด
- ํด๋น ๋ฐฐ๋ฆฌ์ด์ ๋ช
์์ ์ฌ์ฉ์ด ๋ถํ์ํด์ no-op ์ด ๋ ์๋ ์์์ ์์๋์๊ธฐ
- ๋ฐ๋๋๋ค.
- ์ญ์: ๋ณธ ๋ฒ์ญ ์ญ์ ์๋ฒฝํ์ง ์์๋ฐ, ์ด ์ญ์ ๋ถ๋ถ์ ์ผ๋ก๋ ์๋๋ ๊ฒ์ด๊ธฐ๋
- ํฉ๋๋ค. ์ฌํ ๊ธฐ์ ๋ฌธ์๋ค์ด ๊ทธ๋ ๋ฏ ์๋ฒฝํ ์ดํด๋ฅผ ์ํด์๋ ๋ฒ์ญ๋ฌธ๊ณผ ์๋ฌธ์ ํจ๊ป
- ์ฝ์ผ์๋ ๋ฒ์ญ๋ฌธ์ ํ๋์ ๊ฐ์ด๋๋ก ํ์ฉํ์๊ธธ ์ถ์ฒ๋๋ฆฌ๋ฉฐ, ๋ฐ๊ฒฌ๋๋ ์ค์ญ ๋ฑ์
- ๋ํด์๋ ์ธ์ ๋ ์๊ฒฌ์ ๋ถํ๋๋ฆฝ๋๋ค. ๊ณผํ ๋ฒ์ญ์ผ๋ก ์ธํ ์คํด๋ฅผ ์ต์ํํ๊ธฐ ์ํด
- ์ ๋งคํ ๋ถ๋ถ์ด ์์ ๊ฒฝ์ฐ์๋ ์ด์ํจ์ด ์๋๋ผ๋ ์๋์ ์ฉ์ด๋ฅผ ์ฐจ์ฉํฉ๋๋ค.
- =====
- ๋ชฉ์ฐจ:
- =====
- (*) ์ถ์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ๋ชจ๋ธ.
- - ๋๋ฐ์ด์ค ์คํผ๋ ์ด์
.
- - ๋ณด์ฅ์ฌํญ.
- (*) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ฌด์์ธ๊ฐ?
- - ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ์ข
๋ฅ.
- - ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ๋ํด ๊ฐ์ ํด์ ์๋ ๊ฒ.
- - ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด.
- - ์ปจํธ๋กค ์์กด์ฑ.
- - SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ.
- - ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ํ์ค์ ์.
- - ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด vs ๋ก๋ ์์ธก.
- - ์ดํ์ฑ
- (*) ๋ช
์์ ์ปค๋ ๋ฐฐ๋ฆฌ์ด.
- - ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด.
- - CPU ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- - MMIO ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด.
- (*) ์๋ฌต์ ์ปค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- - ๋ฝ Acquisition ํจ์.
- - ์ธํฐ๋ฝํธ ๋นํ์ฑํ ํจ์.
- - ์ฌ๋ฆฝ๊ณผ ์จ์ดํฌ์
ํจ์.
- - ๊ทธ์ธ์ ํจ์๋ค.
- (*) CPU ๊ฐ ACQUIRING ๋ฐฐ๋ฆฌ์ด์ ํจ๊ณผ.
- - Acquire vs ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค.
- - Acquire vs I/O ์ก์ธ์ค.
- (*) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ๊ณณ
- - ํ๋ก์ธ์๊ฐ ์ํธ ์์ฉ.
- - ์ดํ ๋ฏน ์คํผ๋ ์ด์
.
- - ๋๋ฐ์ด์ค ์ก์ธ์ค.
- - ์ธํฐ๋ฝํธ.
- (*) ์ปค๋ I/O ๋ฐฐ๋ฆฌ์ด์ ํจ๊ณผ.
- (*) ๊ฐ์ ๋๋ ๊ฐ์ฅ ์ํ๋ ์คํ ์์ ๋ชจ๋ธ.
- (*) CPU ์บ์์ ์ํฅ.
- - ์บ์ ์ผ๊ด์ฑ.
- - ์บ์ ์ผ๊ด์ฑ vs DMA.
- - ์บ์ ์ผ๊ด์ฑ vs MMIO.
- (*) CPU ๋ค์ด ์ ์ง๋ฅด๋ ์ผ๋ค.
- - ๊ทธ๋ฆฌ๊ณ , Alpha ๊ฐ ์๋ค.
- - ๊ฐ์ ๋จธ์ ๊ฒ์คํธ.
- (*) ์ฌ์ฉ ์.
- - ์ํ์ ๋ฒํผ.
- (*) ์ฐธ๊ณ ๋ฌธํ.
- =======================
- ์ถ์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ๋ชจ๋ธ
- =======================
- ๋ค์๊ณผ ๊ฐ์ด ์ถ์ํ๋ ์์คํ
๋ชจ๋ธ์ ์๊ฐํด ๋ด
์๋ค:
- : :
- : :
- : :
- +-------+ : +--------+ : +-------+
- | | : | | : | |
- | | : | | : | |
- | CPU 1 |<----->| Memory |<----->| CPU 2 |
- | | : | | : | |
- | | : | | : | |
- +-------+ : +--------+ : +-------+
- ^ : ^ : ^
- | : | : |
- | : | : |
- | : v : |
- | : +--------+ : |
- | : | | : |
- | : | | : |
- +---------->| Device |<----------+
- : | | :
- : | | :
- : +--------+ :
- : :
- ํ๋ก๊ทธ๋จ์ ์ฌ๋ฌ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ์คํผ๋ ์ด์
์ ๋ฐ์์ํค๊ณ , ๊ฐ๊ฐ์ CPU ๋ ๊ทธ๋ฐ
- ํ๋ก๊ทธ๋จ๋ค์ ์คํํฉ๋๋ค. ์ถ์ํ๋ CPU ๋ชจ๋ธ์์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ ์์๋
- ๋งค์ฐ ์ํ๋์ด ์๊ณ , CPU ๋ ํ๋ก๊ทธ๋จ์ด ์ธ๊ณผ๊ด๊ณ๋ฅผ ์ด๊ธฐ์ง ์๋ ์ํ๋ก ๊ด๋ฆฌ๋๋ค๊ณ
- ๋ณด์ผ ์๋ง ์๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ ์์ ์ด ์ํ๋ ์ด๋ค ์์๋๋ก๋ ์ฌ๋ฐฐ์นํด
- ๋์์ํฌ ์ ์์ต๋๋ค. ๋น์ทํ๊ฒ, ์ปดํ์ผ๋ฌ ๋ํ ํ๋ก๊ทธ๋จ์ ์ ์์ ๋์์ ํด์น์ง
- ์๋ ํ๋ ๋ด์์๋ ์ด๋ค ์์๋ก๋ ์์ ์ด ์ํ๋ ๋๋ก ์ธ์คํธ๋ญ์
์ ์ฌ๋ฐฐ์น ํ ์
- ์์ต๋๋ค.
- ๋ฐ๋ผ์ ์์ ๋ค์ด์ด๊ทธ๋จ์์ ํ CPU๊ฐ ๋์์ํค๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ด ๋ง๋ค์ด๋ด๋
- ๋ณํ๋ ํด๋น ์คํผ๋ ์ด์
์ด CPU ์ ์์คํ
์ ๋ค๋ฅธ ๋ถ๋ถ๋ค ์ฌ์ด์ ์ธํฐํ์ด์ค(์ ์ )๋ฅผ
- ์ง๋๊ฐ๋ฉด์ ์์คํ
์ ๋๋จธ์ง ๋ถ๋ถ๋ค์ ์ธ์ง๋ฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ค์์ ์ผ๋ จ์ ์ด๋ฒคํธ๋ค์ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- =============== ===============
- { A == 1; B == 2 }
- A = 3; x = B;
- B = 4; y = A;
- ๋ค์ด์ด๊ทธ๋จ์ ๊ฐ์ด๋ฐ์ ์์นํ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ๋ณด์ฌ์ง๊ฒ ๋๋ ์ก์ธ์ค๋ค์ ๋ค์์ ์ด
- 24๊ฐ์ ์กฐํฉ์ผ๋ก ์ฌ๊ตฌ์ฑ๋ ์ ์์ต๋๋ค:
- STORE A=3, STORE B=4, y=LOAD A->3, x=LOAD B->4
- STORE A=3, STORE B=4, x=LOAD B->4, y=LOAD A->3
- STORE A=3, y=LOAD A->3, STORE B=4, x=LOAD B->4
- STORE A=3, y=LOAD A->3, x=LOAD B->2, STORE B=4
- STORE A=3, x=LOAD B->2, STORE B=4, y=LOAD A->3
- STORE A=3, x=LOAD B->2, y=LOAD A->3, STORE B=4
- STORE B=4, STORE A=3, y=LOAD A->3, x=LOAD B->4
- STORE B=4, ...
- ...
- ๋ฐ๋ผ์ ๋ค์์ ๋ค๊ฐ์ง ์กฐํฉ์ ๊ฐ๋ค์ด ๋์ฌ ์ ์์ต๋๋ค:
- x == 2, y == 1
- x == 2, y == 3
- x == 4, y == 1
- x == 4, y == 3
- ํ๋ฐ ๋ ๋์๊ฐ์, ํ CPU ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ๋ฐ์ํ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ ๊ฒฐ๊ณผ๋
- ๋ค๋ฅธ CPU ์์์ ๋ก๋ ์คํผ๋ ์ด์
์ ํตํด ์ธ์ง๋๋๋ฐ, ์ด ๋ ์คํ ์ด๊ฐ ๋ฐ์๋ ์์์
- ๋ค๋ฅธ ์์๋ก ์ธ์ง๋ ์๋ ์์ต๋๋ค.
- ์๋ก, ์๋์ ์ผ๋ จ์ ์ด๋ฒคํธ๋ค์ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- =============== ===============
- { A == 1, B == 2, C == 3, P == &A, Q == &C }
- B = 4; Q = P;
- P = &B D = *Q;
- D ๋ก ์ฝํ์ง๋ ๊ฐ์ CPU 2 ์์ P ๋ก๋ถํฐ ์ฝํ์ง ์ฃผ์๊ฐ์ ์์กด์ ์ด๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์
- ๋ถ๋ช
ํ ๋ฐ์ดํฐ ์์กด์ฑ์ด ์์ต๋๋ค. ํ์ง๋ง ์ด ์ด๋ฒคํธ๋ค์ ์คํ ๊ฒฐ๊ณผ๋ก๋ ์๋์
- ๊ฒฐ๊ณผ๋ค์ด ๋ชจ๋ ๋ํ๋ ์ ์์ต๋๋ค:
- (Q == &A) and (D == 1)
- (Q == &B) and (D == 2)
- (Q == &B) and (D == 4)
- CPU 2 ๋ *Q ์ ๋ก๋๋ฅผ ์์ฒญํ๊ธฐ ์ ์ P ๋ฅผ Q ์ ๋ฃ๊ธฐ ๋๋ฌธ์ D ์ C ๋ฅผ ์ง์ด๋ฃ๋
- ์ผ์ ์์์ ์์๋์ธ์.
- ๋๋ฐ์ด์ค ์คํผ๋ ์ด์
- -------------------
- ์ผ๋ถ ๋๋ฐ์ด์ค๋ ์์ ์ ์ปจํธ๋กค ์ธํฐํ์ด์ค๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ํน์ ์์ญ์ผ๋ก ๋งคํํด์
- ์ ๊ณตํ๋๋ฐ(Memory mapped I/O), ํด๋น ์ปจํธ๋กค ๋ ์ง์คํฐ์ ์ ๊ทผํ๋ ์์๋ ๋งค์ฐ
- ์ค์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋๋ ์ค ํฌํธ ๋ ์ง์คํฐ (A) ์ ๋ฐ์ดํฐ ํฌํธ ๋ ์ง์คํฐ (D)
- ๋ฅผ ํตํด ์ ๊ทผ๋๋ ๋ด๋ถ ๋ ์ง์คํฐ ์งํฉ์ ๊ฐ๋ ์ด๋๋ท ์นด๋๋ฅผ ์๊ฐํด ๋ด
์๋ค. ๋ด๋ถ์
- 5๋ฒ ๋ ์ง์คํฐ๋ฅผ ์ฝ๊ธฐ ์ํด ๋ค์์ ์ฝ๋๊ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค:
- *A = 5;
- x = *D;
- ํ์ง๋ง, ์ด๊ฑด ๋ค์์ ๋ ์กฐํฉ ์ค ํ๋๋ก ๋ง๋ค์ด์ง ์ ์์ต๋๋ค:
- STORE *A = 5, x = LOAD *D
- x = LOAD *D, STORE *A = 5
- ๋๋ฒ์งธ ์กฐํฉ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์จ _ํ์_ ์ฃผ์๋ฅผ ์ค์ ํ๋ฏ๋ก, ์ค๋์์ ์ผ์ผํฌ ๊ฒ๋๋ค.
- ๋ณด์ฅ์ฌํญ
- --------
- CPU ์๊ฒ ๊ธฐ๋ํ ์ ์๋ ์ต์ํ์ ๋ณด์ฅ์ฌํญ ๋ช๊ฐ์ง๊ฐ ์์ต๋๋ค:
- (*) ์ด๋ค CPU ๋ , ์์กด์ฑ์ด ์กด์ฌํ๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ํด๋น CPU ์์ ์๊ฒ
- ์์ด์๋ ์์๋๋ก ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ์ํ ์์ฒญ๋ฉ๋๋ค. ์ฆ, ๋ค์์ ๋ํด์:
- Q = READ_ONCE(P); smp_read_barrier_depends(); D = READ_ONCE(*Q);
- CPU ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ํ์ค๋ฅผ ์ํ ์์ฒญํฉ๋๋ค:
- Q = LOAD P, D = LOAD *Q
- ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ํ์ค ๋ด์์์ ์์๋ ํญ์ ์ง์ผ์ง๋๋ค. ๋๋ถ๋ถ์ ์์คํ
์์
- smp_read_barrier_depends() ๋ ์๋ฌด์ผ๋ ์ํ์ง๋ง DEC Alpha ์์๋
- ๋ช
์์ ์ผ๋ก ์ฌ์ฉ๋์ด์ผ ํฉ๋๋ค. ๋ณดํต์ ๊ฒฝ์ฐ์๋ smp_read_barrier_depends()
- ๋ฅผ ์ง์ ์ฌ์ฉํ๋ ๋์ rcu_dereference() ๊ฐ์ ๊ฒ๋ค์ ์ฌ์ฉํด์ผ ํจ์
- ์์๋์ธ์.
- (*) ํน์ CPU ๋ด์์ ๊ฒน์น๋ ์์ญ์ ๋ฉ๋ชจ๋ฆฌ์ ํํด์ง๋ ๋ก๋์ ์คํ ์ด ๋ค์ ํด๋น
- CPU ์์์๋ ์์๊ฐ ๋ฐ๋์ง ์์ ๊ฒ์ผ๋ก ๋ณด์ฌ์ง๋๋ค. ์ฆ, ๋ค์์ ๋ํด์:
- a = READ_ONCE(*X); WRITE_ONCE(*X, b);
- CPU ๋ ๋ค์์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ํ์ค๋ง์ ๋ฉ๋ชจ๋ฆฌ์ ์์ฒญํ ๊ฒ๋๋ค:
- a = LOAD *X, STORE *X = b
- ๊ทธ๋ฆฌ๊ณ ๋ค์์ ๋ํด์๋:
- WRITE_ONCE(*X, c); d = READ_ONCE(*X);
- CPU ๋ ๋ค์์ ์ํ ์์ฒญ๋ง์ ๋ง๋ค์ด ๋
๋๋ค:
- STORE *X = c, d = LOAD *X
- (๋ก๋ ์คํผ๋ ์ด์
๊ณผ ์คํ ์ด ์คํผ๋ ์ด์
์ด ๊ฒน์น๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ํด
- ์ํ๋๋ค๋ฉด ํด๋น ์คํผ๋ ์ด์
๋ค์ ๊ฒน์น๋ค๊ณ ํํ๋ฉ๋๋ค).
- ๊ทธ๋ฆฌ๊ณ _๋ฐ๋์_ ๋๋ _์ ๋๋ก_ ๊ฐ์ ํ๊ฑฐ๋ ๊ฐ์ ํ์ง ๋ง์์ผ ํ๋ ๊ฒ๋ค์ด ์์ต๋๋ค:
- (*) ์ปดํ์ผ๋ฌ๊ฐ READ_ONCE() ๋ WRITE_ONCE() ๋ก ๋ณดํธ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ฅผ
- ๋น์ ์ด ์ํ๋ ๋๋ก ํ ๊ฒ์ด๋ผ๋ ๊ฐ์ ์ _์ ๋๋ก_ ํด์ ์๋ฉ๋๋ค. ๊ทธ๊ฒ๋ค์ด
- ์๋ค๋ฉด, ์ปดํ์ผ๋ฌ๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด ์น์
์์ ๋ค๋ฃจ๊ฒ ๋ , ๋ชจ๋ "์ฐฝ์์ ์ธ"
- ๋ณ๊ฒฝ๋ค์ ๋ง๋ค์ด๋ผ ๊ถํ์ ๊ฐ๊ฒ ๋ฉ๋๋ค.
- (*) ๊ฐ๋ณ์ ์ธ ๋ก๋์ ์คํ ์ด๋ค์ด ์ฃผ์ด์ง ์์๋๋ก ์์ฒญ๋ ๊ฒ์ด๋ผ๋ ๊ฐ์ ์ _์ ๋๋ก_
- ํ์ง ๋ง์์ผ ํฉ๋๋ค. ์ด ๋ง์ ๊ณง:
- X = *A; Y = *B; *D = Z;
- ๋ ๋ค์์ ๊ฒ๋ค ์ค ์ด๋ ๊ฒ์ผ๋ก๋ ๋ง๋ค์ด์ง ์ ์๋ค๋ ์๋ฏธ์
๋๋ค:
- X = LOAD *A, Y = LOAD *B, STORE *D = Z
- X = LOAD *A, STORE *D = Z, Y = LOAD *B
- Y = LOAD *B, X = LOAD *A, STORE *D = Z
- Y = LOAD *B, STORE *D = Z, X = LOAD *A
- STORE *D = Z, X = LOAD *A, Y = LOAD *B
- STORE *D = Z, Y = LOAD *B, X = LOAD *A
- (*) ๊ฒน์น๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ํฉ์ณ์ง๊ฑฐ๋ ๋ฒ๋ ค์ง ์ ์์์ _๋ฐ๋์_ ๊ฐ์ ํด์ผ
- ํฉ๋๋ค. ๋ค์์ ์ฝ๋๋:
- X = *A; Y = *(A + 4);
- ๋ค์์ ๊ฒ๋ค ์ค ๋ญ๋ ๋ ์ ์์ต๋๋ค:
- X = LOAD *A; Y = LOAD *(A + 4);
- Y = LOAD *(A + 4); X = LOAD *A;
- {X, Y} = LOAD {*A, *(A + 4) };
- ๊ทธ๋ฆฌ๊ณ :
- *A = X; *(A + 4) = Y;
- ๋ ๋ค์ ์ค ๋ญ๋ ๋ ์ ์์ต๋๋ค:
- STORE *A = X; STORE *(A + 4) = Y;
- STORE *(A + 4) = Y; STORE *A = X;
- STORE {*A, *(A + 4) } = {X, Y};
- ๊ทธ๋ฆฌ๊ณ ๋ณด์ฅ์ฌํญ์ ๋ฐ๋๋๋ ๊ฒ๋ค(anti-guarantees)์ด ์์ต๋๋ค:
- (*) ์ด ๋ณด์ฅ์ฌํญ๋ค์ bitfield ์๋ ์ ์ฉ๋์ง ์๋๋ฐ, ์ปดํ์ผ๋ฌ๋ค์ bitfield ๋ฅผ
- ์์ ํ๋ ์ฝ๋๋ฅผ ์์ฑํ ๋ ์์์ฑ ์๋(non-atomic) ์ฝ๊ณ -์์ ํ๊ณ -์ฐ๋
- ์ธ์คํธ๋ญ์
๋ค์ ์กฐํฉ์ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์
- ๋๊ธฐํ์ bitfield ๋ฅผ ์ฌ์ฉํ๋ ค ํ์ง ๋ง์ญ์์ค.
- (*) bitfield ๋ค์ด ์ฌ๋ฌ ๋ฝ์ผ๋ก ๋ณดํธ๋๋ ๊ฒฝ์ฐ๋ผ ํ๋๋ผ๋, ํ๋์ bitfield ์
- ๋ชจ๋ ํ๋๋ค์ ํ๋์ ๋ฝ์ผ๋ก ๋ณดํธ๋์ด์ผ ํฉ๋๋ค. ๋ง์ฝ ํ bitfield ์ ๋
- ํ๋๊ฐ ์๋ก ๋ค๋ฅธ ๋ฝ์ผ๋ก ๋ณดํธ๋๋ค๋ฉด, ์ปดํ์ผ๋ฌ์ ์์์ฑ ์๋
- ์ฝ๊ณ -์์ ํ๊ณ -์ฐ๋ ์ธ์คํธ๋ญ์
์กฐํฉ์ ํ ํ๋์์ ์
๋ฐ์ดํธ๊ฐ ๊ทผ์ฒ์
- ํ๋์๋ ์ํฅ์ ๋ผ์น๊ฒ ํ ์ ์์ต๋๋ค.
- (*) ์ด ๋ณด์ฅ์ฌํญ๋ค์ ์ ์ ํ๊ฒ ์ ๋ ฌ๋๊ณ ํฌ๊ธฐ๊ฐ ์กํ ์ค์นผ๋ผ ๋ณ์๋ค์ ๋ํด์๋ง
- ์ ์ฉ๋ฉ๋๋ค. "์ ์ ํ๊ฒ ํฌ๊ธฐ๊ฐ ์กํ" ์ด๋ผํจ์ ํ์ฌ๋ก์จ๋ "char", "short",
- "int" ๊ทธ๋ฆฌ๊ณ "long" ๊ณผ ๊ฐ์ ํฌ๊ธฐ์ ๋ณ์๋ค์ ์๋ฏธํฉ๋๋ค. "์ ์ ํ๊ฒ ์ ๋ ฌ๋"
- ์ ์์ฐ์ค๋ฐ ์ ๋ ฌ์ ์๋ฏธํ๋๋ฐ, ๋ฐ๋ผ์ "char" ์ ๋ํด์๋ ์๋ฌด ์ ์ฝ์ด ์๊ณ ,
- "short" ์ ๋ํด์๋ 2๋ฐ์ดํธ ์ ๋ ฌ์, "int" ์๋ 4๋ฐ์ดํธ ์ ๋ ฌ์, ๊ทธ๋ฆฌ๊ณ
- "long" ์ ๋ํด์๋ 32-bit ์์คํ
์ธ์ง 64-bit ์์คํ
์ธ์ง์ ๋ฐ๋ผ 4๋ฐ์ดํธ ๋๋
- 8๋ฐ์ดํธ ์ ๋ ฌ์ ์๋ฏธํฉ๋๋ค. ์ด ๋ณด์ฅ์ฌํญ๋ค์ C11 ํ์ค์์ ์๊ฐ๋์์ผ๋ฏ๋ก,
- C11 ์ ์ ์ค๋๋ ์ปดํ์ผ๋ฌ(์๋ฅผ ๋ค์ด, gcc 4.6) ๋ฅผ ์ฌ์ฉํ ๋์ ์ฃผ์ํ์๊ธฐ
- ๋ฐ๋๋๋ค. ํ์ค์ ์ด ๋ณด์ฅ์ฌํญ๋ค์ "memory location" ์ ์ ์ํ๋ 3.14
- ์น์
์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช
๋์ด ์์ต๋๋ค:
- (์ญ์: ์ธ์ฉ๋ฌธ์ด๋ฏ๋ก ๋ฒ์ญํ์ง ์์ต๋๋ค)
- memory location
- either an object of scalar type, or a maximal sequence
- of adjacent bit-fields all having nonzero width
- NOTE 1: Two threads of execution can update and access
- separate memory locations without interfering with
- each other.
- NOTE 2: A bit-field and an adjacent non-bit-field member
- are in separate memory locations. The same applies
- to two bit-fields, if one is declared inside a nested
- structure declaration and the other is not, or if the two
- are separated by a zero-length bit-field declaration,
- or if they are separated by a non-bit-field member
- declaration. It is not safe to concurrently update two
- bit-fields in the same structure if all members declared
- between them are also bit-fields, no matter what the
- sizes of those intervening bit-fields happen to be.
- =========================
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ฌด์์ธ๊ฐ?
- =========================
- ์์์ ๋ดค๋ฏ์ด, ์ํธ๊ฐ ์์กด์ฑ์ด ์๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ ์ค์ ๋ก๋ ๋ฌด์์์
- ์์๋ก ์ํ๋ ์ ์์ผ๋ฉฐ, ์ด๋ CPU ์ CPU ๊ฐ์ ์ํธ์์ฉ์ด๋ I/O ์ ๋ฌธ์ ๊ฐ ๋ ์
- ์์ต๋๋ค. ๋ฐ๋ผ์ ์ปดํ์ผ๋ฌ์ CPU ๊ฐ ์์๋ฅผ ๋ฐ๊พธ๋๋ฐ ์ ์ฝ์ ๊ฑธ ์ ์๋๋ก ๊ฐ์
ํ
- ์ ์๋ ์ด๋ค ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๊ทธ๋ฐ ๊ฐ์
์๋จ์
๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ด์ ๋ ์๊ณผ
- ๋ค ์์ธก์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค ๊ฐ์ ๋ถ๋ถ์ ์์๊ฐ ์กด์ฌํ๋๋ก ํ๋ ํจ๊ณผ๋ฅผ ์ค๋๋ค.
- ์์คํ
์ CPU ๋ค๊ณผ ์ฌ๋ฌ ๋๋ฐ์ด์ค๋ค์ ์ฑ๋ฅ์ ์ฌ๋ฆฌ๊ธฐ ์ํด ๋ช
๋ น์ด ์ฌ๋ฐฐ์น, ์คํ
- ์ ์, ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ ์กฐํฉ, ์์ธก์ ๋ก๋(speculative load), ๋ธ๋์น
- ์์ธก(speculative branch prediction), ๋ค์ํ ์ข
๋ฅ์ ์บ์ฑ(caching) ๋ฑ์ ๋ค์ํ
- ํธ๋ฆญ์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ๊ฐ์ ๋ ฅ์ ์ค์ํฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ ์ด๋ฐ
- ํธ๋ฆญ๋ค์ ๋ฌดํจ๋ก ํ๊ฑฐ๋ ์ต์ ํ๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋์ด์ ธ์ ์ฝ๋๊ฐ ์ฌ๋ฌ CPU ์
- ๋๋ฐ์ด์ค๋ค ๊ฐ์ ์ํธ์์ฉ์ ์ ์์ ์ผ๋ก ์ ์ดํ ์ ์๊ฒ ํด์ค๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ์ข
๋ฅ
- --------------------
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ค๊ฐ์ ๊ธฐ๋ณธ ํ์
์ผ๋ก ๋ถ๋ฅ๋ฉ๋๋ค:
- (1) ์ฐ๊ธฐ (๋๋ ์คํ ์ด) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์์คํ
์ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค์ ํด๋น ๋ฐฐ๋ฆฌ์ด๋ณด๋ค ์์
- ๋ช
์๋ ๋ชจ๋ STORE ์คํผ๋ ์ด์
๋ค์ด ํด๋น ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ช
์๋ ๋ชจ๋ STORE
- ์คํผ๋ ์ด์
๋ค๋ณด๋ค ๋จผ์ ์ํ๋ ๊ฒ์ผ๋ก ๋ณด์ผ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
- ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ ๋ํ ๋ถ๋ถ์ ์์ ์ธ์ฐ๊ธฐ์
๋๋ค; ๋ก๋
- ์คํผ๋ ์ด์
๋ค์ ๋ํด์๋ ์ด๋ค ์ํฅ๋ ๋ผ์น์ง ์์ต๋๋ค.
- CPU ๋ ์๊ฐ์ ํ๋ฆ์ ๋ฐ๋ผ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ์ผ๋ จ์ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์
- ํ๋์ฉ ์์ฒญํด ์ง์ด๋ฃ์ต๋๋ค. ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด ์์ ๋ชจ๋ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์
- ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ชจ๋ ์คํ ์ด ์คํผ๋ ์ด์
๋ค๋ณด๋ค _์์_ ์ํ๋ ๊ฒ๋๋ค.
- [!] ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ค์ ์ฝ๊ธฐ ๋๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด์ ํจ๊ป ์ง์ ๋ง์ถฐ
- ์ฌ์ฉ๋์ด์ผ๋ง ํจ์ ์์๋์ธ์; "SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- (2) ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด.
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด์ ๋ณด๋ค ์ํ๋ ํํ์
๋๋ค. ๋๊ฐ์ ๋ก๋
- ์คํผ๋ ์ด์
์ด ์๊ณ ๋๋ฒ์งธ ๊ฒ์ด ์ฒซ๋ฒ์งธ ๊ฒ์ ๊ฒฐ๊ณผ์ ์์กดํ๊ณ ์์ ๋(์:
- ๋๋ฒ์งธ ๋ก๋๊ฐ ์ฐธ์กฐํ ์ฃผ์๋ฅผ ์ฒซ๋ฒ์งธ ๋ก๋๊ฐ ์ฝ๋ ๊ฒฝ์ฐ), ๋๋ฒ์งธ ๋ก๋๊ฐ ์ฝ์ด์ฌ
- ๋ฐ์ดํฐ๋ ์ฒซ๋ฒ์งธ ๋ก๋์ ์ํด ๊ทธ ์ฃผ์๊ฐ ์ป์ด์ง๊ธฐ ์ ์ ์
๋ฐ์ดํธ ๋์ด ์์์
- ๋ณด์ฅํ๊ธฐ ์ํด์ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์ํธ ์์กด์ ์ธ ๋ก๋ ์คํผ๋ ์ด์
๋ค ์ฌ์ด์ ๋ถ๋ถ์ ์์
- ์ธ์ฐ๊ธฐ์
๋๋ค; ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ด๋ ๋
๋ฆฝ์ ์ธ ๋ก๋๋ค, ๋๋ ์ค๋ณต๋๋
- ๋ก๋๋ค์ ๋ํด์๋ ์ด๋ค ์ํฅ๋ ๋ผ์น์ง ์์ต๋๋ค.
- (1) ์์ ์ธ๊ธํ๋ฏ์ด, ์์คํ
์ CPU ๋ค์ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ์ผ๋ จ์ ์คํ ์ด
- ์คํผ๋ ์ด์
๋ค์ ๋์ ธ ๋ฃ๊ณ ์์ผ๋ฉฐ, ๊ฑฐ๊ธฐ์ ๊ด์ฌ์ด ์๋ ๋ค๋ฅธ CPU ๋ ๊ทธ
- ์คํผ๋ ์ด์
๋ค์ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ด ์คํํ ๊ฒฐ๊ณผ๋ฅผ ์ธ์งํ ์ ์์ต๋๋ค. ์ด์ฒ๋ผ
- ๋ค๋ฅธ CPU ์ ์คํ ์ด ์คํผ๋ ์ด์
์ ๊ฒฐ๊ณผ์ ๊ด์ฌ์ ๋๊ณ ์๋ CPU ๊ฐ ์ํ ์์ฒญํ
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋, ๋ฐฐ๋ฆฌ์ด ์์ ์ด๋ค ๋ก๋ ์คํผ๋ ์ด์
์ด ๋ค๋ฅธ CPU ์์
- ๋์ ธ ๋ฃ์ ์คํ ์ด ์คํผ๋ ์ด์
๊ณผ ๊ฐ์ ์์ญ์ ํฅํ๋ค๋ฉด, ๊ทธ๋ฐ ์คํ ์ด
- ์คํผ๋ ์ด์
๋ค์ด ๋ง๋ค์ด๋ด๋ ๊ฒฐ๊ณผ๊ฐ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ก๋
- ์คํผ๋ ์ด์
๋ค์๊ฒ๋ ๋ณด์ผ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
- ์ด ์์ ์ธ์ฐ๊ธฐ ์ ์ฝ์ ๋ํ ๊ทธ๋ฆผ์ ๋ณด๊ธฐ ์ํด์ "๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ํ์ค์ ์"
- ์๋ธ์น์
์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
- [!] ์ฒซ๋ฒ์งธ ๋ก๋๋ ๋ฐ๋์ _๋ฐ์ดํฐ_ ์์กด์ฑ์ ๊ฐ์ ธ์ผ์ง ์ปจํธ๋กค ์์กด์ฑ์ ๊ฐ์ ธ์ผ
- ํ๋๊ฒ ์๋์ ์์๋์ญ์์ค. ๋ง์ฝ ๋๋ฒ์งธ ๋ก๋๋ฅผ ์ํ ์ฃผ์๊ฐ ์ฒซ๋ฒ์งธ ๋ก๋์
- ์์กด์ ์ด์ง๋ง ๊ทธ ์์กด์ฑ์ ์กฐ๊ฑด์ ์ด์ง ๊ทธ ์ฃผ์ ์์ฒด๋ฅผ ๊ฐ์ ธ์ค๋๊ฒ ์๋๋ผ๋ฉด,
- ๊ทธ๊ฒ์ _์ปจํธ๋กค_ ์์กด์ฑ์ด๊ณ , ์ด ๊ฒฝ์ฐ์๋ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๊ทธ๋ณด๋ค ๊ฐ๋ ฅํ
- ๋ฌด์ธ๊ฐ๊ฐ ํ์ํฉ๋๋ค. ๋ ์์ธํ ๋ด์ฉ์ ์ํด์๋ "์ปจํธ๋กค ์์กด์ฑ" ์๋ธ์น์
์
- ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
- [!] ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ๋ณดํต ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ ํจ๊ป ์ง์ ๋ง์ถฐ ์ฌ์ฉ๋์ด์ผ
- ํฉ๋๋ค; "SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- (3) ์ฝ๊ธฐ (๋๋ ๋ก๋) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด ๊ธฐ๋ฅ์ ๋ณด์ฅ์ฌํญ์ ๋ํด์ ๋ฐฐ๋ฆฌ์ด๋ณด๋ค
- ์์ ๋ช
์๋ ๋ชจ๋ LOAD ์คํผ๋ ์ด์
๋ค์ด ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ช
์๋๋ ๋ชจ๋ LOAD
- ์คํผ๋ ์ด์
๋ค๋ณด๋ค ๋จผ์ ํํด์ง ๊ฒ์ผ๋ก ์์คํ
์ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค์ ๋ณด์ฌ์ง ๊ฒ์
- ๋ณด์ฅํฉ๋๋ค.
- ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ก๋ ์คํผ๋ ์ด์
์ ํํด์ง๋ ๋ถ๋ถ์ ์์ ์ธ์ฐ๊ธฐ์
๋๋ค; ์คํ ์ด
- ์คํผ๋ ์ด์
์ ๋ํด์๋ ์ด๋ค ์ํฅ๋ ๋ผ์น์ง ์์ต๋๋ค.
- ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ด์ฅํ๋ฏ๋ก ๋ฐ์ดํฐ ์์กด์ฑ
- ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋์ ํ ์ ์์ต๋๋ค.
- [!] ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ ํจ๊ป ์ง์ ๋ง์ถฐ ์ฌ์ฉ๋์ด์ผ
- ํฉ๋๋ค; "SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- (4) ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- ๋ฒ์ฉ(general) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐฐ๋ฆฌ์ด๋ณด๋ค ์์ ๋ช
์๋ ๋ชจ๋ LOAD ์ STORE
- ์คํผ๋ ์ด์
๋ค์ด ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ช
์๋ ๋ชจ๋ LOAD ์ STORE ์คํผ๋ ์ด์
๋ค๋ณด๋ค
- ๋จผ์ ์ํ๋ ๊ฒ์ผ๋ก ์์คํ
์ ๋๋จธ์ง ์ปดํฌ๋ํธ๋ค์ ๋ณด์ด๊ฒ ๋จ์ ๋ณด์ฅํฉ๋๋ค.
- ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋ก๋์ ์คํ ์ด ๋ชจ๋์ ๋ํ ๋ถ๋ถ์ ์์ ์ธ์ฐ๊ธฐ์
๋๋ค.
- ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด, ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋ชจ๋๋ฅผ
- ๋ด์ฅํ๋ฏ๋ก, ๋ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ชจ๋ ๋์ ํ ์ ์์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ ๋๊ฐ์ ๋ช
์์ ์ด์ง ์์ ํ์
์ด ์์ต๋๋ค:
- (5) ACQUIRE ์คํผ๋ ์ด์
.
- ์ด ํ์
์ ์คํผ๋ ์ด์
์ ๋จ๋ฐฉํฅ์ ํฌ๊ณผ์ฑ ๋ฐฐ๋ฆฌ์ด์ฒ๋ผ ๋์ํฉ๋๋ค. ACQUIRE
- ์คํผ๋ ์ด์
๋ค์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ด ACQUIRE ์คํผ๋ ์ด์
ํ์
- ์ผ์ด๋ ๊ฒ์ผ๋ก ์์คํ
์ ๋๋จธ์ง ์ปดํฌ๋ํธ๋ค์ ๋ณด์ด๊ฒ ๋ ๊ฒ์ด ๋ณด์ฅ๋ฉ๋๋ค.
- LOCK ์คํผ๋ ์ด์
๊ณผ smp_load_acquire(), smp_cond_acquire() ์คํผ๋ ์ด์
๋
- ACQUIRE ์คํผ๋ ์ด์
์ ํฌํจ๋ฉ๋๋ค. smp_cond_acquire() ์คํผ๋ ์ด์
์ ์ปจํธ๋กค
- ์์กด์ฑ๊ณผ smp_rmb() ๋ฅผ ์ฌ์ฉํด์ ACQUIRE ์ ์๋ฏธ์ ์๊ตฌ์ฌํญ(semantic)์
- ์ถฉ์กฑ์ํต๋๋ค.
- ACQUIRE ์คํผ๋ ์ด์
์์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ ACQUIRE ์คํผ๋ ์ด์
์๋ฃ ํ์
- ์ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค.
- ACQUIRE ์คํผ๋ ์ด์
์ ๊ฑฐ์ ํญ์ RELEASE ์คํผ๋ ์ด์
๊ณผ ์ง์ ์ง์ด ์ฌ์ฉ๋์ด์ผ
- ํฉ๋๋ค.
- (6) RELEASE ์คํผ๋ ์ด์
.
- ์ด ํ์
์ ์คํผ๋ ์ด์
๋ค๋ ๋จ๋ฐฉํฅ ํฌ๊ณผ์ฑ ๋ฐฐ๋ฆฌ์ด์ฒ๋ผ ๋์ํฉ๋๋ค. RELEASE
- ์คํผ๋ ์ด์
์์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ RELEASE ์คํผ๋ ์ด์
์ ์ ์๋ฃ๋
- ๊ฒ์ผ๋ก ์์คํ
์ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค์ ๋ณด์ฌ์ง ๊ฒ์ด ๋ณด์ฅ๋ฉ๋๋ค. UNLOCK ๋ฅ์
- ์คํผ๋ ์ด์
๋ค๊ณผ smp_store_release() ์คํผ๋ ์ด์
๋ RELEASE ์คํผ๋ ์ด์
์
- ์ผ์ข
์
๋๋ค.
- RELEASE ์คํผ๋ ์ด์
๋ค์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ RELEASE ์คํผ๋ ์ด์
์ด
- ์๋ฃ๋๊ธฐ ์ ์ ํํด์ง ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค.
- ACQUIRE ์ RELEASE ์คํผ๋ ์ด์
์ ์ฌ์ฉ์ ์ผ๋ฐ์ ์ผ๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์
- ํ์์ฑ์ ์์ฑ๋๋ค (ํ์ง๋ง "MMIO ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด" ์๋ธ์น์
์์ ์ค๋ช
๋๋ ์์ธ๋ฅผ
- ์์๋์ธ์). ๋ํ, RELEASE+ACQUIRE ์กฐํฉ์ ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ฒ๋ผ ๋์ํ
- ๊ฒ์ ๋ณด์ฅํ์ง -์์ต๋๋ค-. ํ์ง๋ง, ์ด๋ค ๋ณ์์ ๋ํ RELEASE ์คํผ๋ ์ด์
์
- ์์๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ์ํ ๊ฒฐ๊ณผ๋ ์ด RELEASE ์คํผ๋ ์ด์
์ ๋ค์ด์ด ๊ฐ์
- ๋ณ์์ ๋ํด ์ํ๋ ACQUIRE ์คํผ๋ ์ด์
์ ๋ค๋ฐ๋ฅด๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค์๋ ๋ณด์ฌ์ง
- ๊ฒ์ด ๋ณด์ฅ๋ฉ๋๋ค. ๋ค๋ฅด๊ฒ ๋งํ์๋ฉด, ์ฃผ์ด์ง ๋ณ์์ ํฌ๋ฆฌํฐ์ปฌ ์น์
์์๋, ํด๋น
- ๋ณ์์ ๋ํ ์์ ํฌ๋ฆฌํฐ์ปฌ ์น์
์์์ ๋ชจ๋ ์ก์ธ์ค๋ค์ด ์๋ฃ๋์์ ๊ฒ์
- ๋ณด์ฅํฉ๋๋ค.
- ์ฆ, ACQUIRE ๋ ์ต์ํ์ "์ทจ๋" ๋์์ฒ๋ผ, ๊ทธ๋ฆฌ๊ณ RELEASE ๋ ์ต์ํ์ "๊ณต๊ฐ"
- ์ฒ๋ผ ๋์ํ๋ค๋ ์๋ฏธ์
๋๋ค.
- atomic_ops.txt ์์ ์ค๋ช
๋๋ ์ดํ ๋ฏน ์คํผ๋ ์ด์
๋ค ์ค์๋ ์์ ํ ์์์กํ ๊ฒ๋ค๊ณผ
- (๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ์ง ์๋) ์ํ๋ ์์์ ๊ฒ๋ค ์ธ์ ACQUIRE ์ RELEASE ๋ถ๋ฅ์
- ๊ฒ๋ค๋ ์กด์ฌํฉ๋๋ค. ๋ก๋์ ์คํ ์ด๋ฅผ ๋ชจ๋ ์ํํ๋ ์กฐํฉ๋ ์ดํ ๋ฏน ์คํผ๋ ์ด์
์์,
- ACQUIRE ๋ ํด๋น ์คํผ๋ ์ด์
์ ๋ก๋ ๋ถ๋ถ์๋ง ์ ์ฉ๋๊ณ RELEASE ๋ ํด๋น
- ์คํผ๋ ์ด์
์ ์คํ ์ด ๋ถ๋ถ์๋ง ์ ์ฉ๋ฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ ๋ CPU ๊ฐ, ๋๋ CPU ์ ๋๋ฐ์ด์ค ๊ฐ์ ์ํธ์์ฉ์ ๊ฐ๋ฅ์ฑ์ด ์์
- ๋์๋ง ํ์ํฉ๋๋ค. ๋ง์ฝ ์ด๋ค ์ฝ๋์ ๊ทธ๋ฐ ์ํธ์์ฉ์ด ์์ ๊ฒ์ด ๋ณด์ฅ๋๋ค๋ฉด, ํด๋น
- ์ฝ๋์์๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
- ์ด๊ฒ๋ค์ _์ต์ํ์_ ๋ณด์ฅ์ฌํญ๋ค์์ ์์๋์ธ์. ๋ค๋ฅธ ์ํคํ
์ณ์์๋ ๋ ๊ฐ๋ ฅํ
- ๋ณด์ฅ์ฌํญ์ ์ ๊ณตํ ์๋ ์์ต๋๋ค๋ง, ๊ทธ๋ฐ ๋ณด์ฅ์ฌํญ์ ์ํคํ
์ณ ์ข
์์ ์ฝ๋ ์ด์ธ์
- ๋ถ๋ถ์์๋ ์ ๋ขฐ๋์ง _์์_ ๊ฒ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ๋ํด ๊ฐ์ ํด์ ์๋ ๊ฒ
- -------------------------------------
- ๋ฆฌ๋
์ค ์ปค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ด ๋ณด์ฅํ์ง ์๋ ๊ฒ๋ค์ด ์์ต๋๋ค:
- (*) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์์์ ๋ช
์๋ ์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋ช
๋ น์ ์ํ
- ์๋ฃ ์์ ๊น์ง _์๋ฃ_ ๋ ๊ฒ์ด๋ ๋ณด์ฅ์ ์์ต๋๋ค; ๋ฐฐ๋ฆฌ์ด๊ฐ ํ๋ ์ผ์ CPU ์
- ์ก์ธ์ค ํ์ ํน์ ํ์
์ ์ก์ธ์ค๋ค์ ๋์ ์ ์๋ ์ ์ ๊ธ๋ ๊ฒ์ผ๋ก ์๊ฐ๋ ์
- ์์ต๋๋ค.
- (*) ํ CPU ์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ํํ๋๊ฒ ์์คํ
์ ๋ค๋ฅธ CPU ๋ ํ๋์จ์ด์
- ์ด๋ค ์ง์ ์ ์ธ ์ํฅ์ ๋ผ์น๋ค๋ ๋ณด์ฅ์ ์กด์ฌํ์ง ์์ต๋๋ค. ๋ฐฐ๋ฆฌ์ด ์ํ์ด
- ๋ง๋๋ ๊ฐ์ ์ ์ํฅ์ ๋๋ฒ์งธ CPU ๊ฐ ์ฒซ๋ฒ์งธ CPU ์ ์ก์ธ์ค๋ค์ ๊ฒฐ๊ณผ๋ฅผ
- ๋ฐ๋ผ๋ณด๋ ์์๊ฐ ๋ฉ๋๋ค๋ง, ๋ค์ ํญ๋ชฉ์ ๋ณด์ธ์:
- (*) ์ฒซ๋ฒ์งธ CPU ๊ฐ ๋๋ฒ์งธ CPU ์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ผ๋ณผ ๋, _์ค๋ น_
- ๋๋ฒ์งธ CPU ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ๋ค ํด๋, ์ฒซ๋ฒ์งธ CPU _๋ํ_ ๊ทธ์ ๋ง๋
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ("SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ" ์๋ธ์น์
์
- ์ฐธ๊ณ ํ์ธ์) ๊ทธ ๊ฒฐ๊ณผ๊ฐ ์ฌ๋ฐ๋ฅธ ์์๋ก ๋ณด์ฌ์ง๋ค๋ ๋ณด์ฅ์ ์์ต๋๋ค.
- (*) CPU ๋ฐ๊นฅ์ ํ๋์จ์ด[*] ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ์์๋ฅผ ๋ฐ๊พธ์ง ์๋๋ค๋ ๋ณด์ฅ์
- ์กด์ฌํ์ง ์์ต๋๋ค. CPU ์บ์ ์ผ๊ด์ฑ ๋ฉ์ปค๋์ฆ์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ๊ฐ์ ์
- ์ํฅ์ CPU ์ฌ์ด์ ์ ํํ๊ธด ํ์ง๋ง, ์์๋๋ก ์ ํํ์ง๋ ์์ ์ ์์ต๋๋ค.
- [*] ๋ฒ์ค ๋ง์คํฐ๋ง DMA ์ ์ผ๊ด์ฑ์ ๋ํด์๋ ๋ค์์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค:
- Documentation/PCI/pci.txt
- Documentation/DMA-API-HOWTO.txt
- Documentation/DMA-API.txt
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด
- --------------------
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด์ ์ฌ์ฉ์ ์์ด ์ง์ผ์ผ ํ๋ ์ฌํญ๋ค์ ์ฝ๊ฐ ๋ฏธ๋ฌํ๊ณ , ๋ฐ์ดํฐ
- ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๊ฐ ์ฌ์ฉ๋์ด์ผ ํ๋ ์ํฉ๋ ํญ์ ๋ช
๋ฐฑํ์ง๋ ์์ต๋๋ค. ์ค๋ช
์ ์ํด
- ๋ค์์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- =============== ===============
- { A == 1, B == 2, C == 3, P == &A, Q == &C }
- B = 4;
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(P, &B)
- Q = READ_ONCE(P);
- D = *Q;
- ์ฌ๊ธฐ์ ๋ถ๋ช
ํ ๋ฐ์ดํฐ ์์กด์ฑ์ด ์กด์ฌํ๋ฏ๋ก, ์ด ์ํ์ค๊ฐ ๋๋ฌ์ ๋ Q ๋ &A ๋๋ &B
- ์ผ ๊ฒ์ด๊ณ , ๋ฐ๋ผ์:
- (Q == &A) ๋ (D == 1) ๋ฅผ,
- (Q == &B) ๋ (D == 4) ๋ฅผ ์๋ฏธํฉ๋๋ค.
- ํ์ง๋ง! CPU 2 ๋ B ์ ์
๋ฐ์ดํธ๋ฅผ ์ธ์ํ๊ธฐ ์ ์ P ์ ์
๋ฐ์ดํธ๋ฅผ ์ธ์ํ ์ ์๊ณ ,
- ๋ฐ๋ผ์ ๋ค์์ ๊ฒฐ๊ณผ๊ฐ ๊ฐ๋ฅํฉ๋๋ค:
- (Q == &B) and (D == 2) ????
- ์ด๋ฐ ๊ฒฐ๊ณผ๋ ์ผ๊ด์ฑ์ด๋ ์ธ๊ณผ ๊ด๊ณ ์ ์ง๊ฐ ์คํจํ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์๋ ์๊ฒ ์ง๋ง,
- ๊ทธ๋ ์ง ์์ต๋๋ค, ๊ทธ๋ฆฌ๊ณ ์ด ํ์์ (DEC Alpha ์ ๊ฐ์) ์ฌ๋ฌ CPU ์์ ์ค์ ๋ก
- ๋ฐ๊ฒฌ๋ ์ ์์ต๋๋ค.
- ์ด ๋ฌธ์ ์ํฉ์ ์ ๋๋ก ํด๊ฒฐํ๊ธฐ ์ํด, ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ๊ทธ๋ณด๋ค ๊ฐํ๋
- ๋ฌด์ธ๊ฐ๊ฐ ์ฃผ์๋ฅผ ์ฝ์ด์ฌ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ๋ ์ฌ์ด์ ์ถ๊ฐ๋์ด์ผ๋ง ํฉ๋๋ค:
- CPU 1 CPU 2
- =============== ===============
- { A == 1, B == 2, C == 3, P == &A, Q == &C }
- B = 4;
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(P, &B);
- Q = READ_ONCE(P);
- <๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด>
- D = *Q;
- ์ด ๋ณ๊ฒฝ์ ์์ ์ฒ์ ๋๊ฐ์ง ๊ฒฐ๊ณผ ์ค ํ๋๋ง์ด ๋ฐ์ํ ์ ์๊ณ , ์ธ๋ฒ์งธ์ ๊ฒฐ๊ณผ๋
- ๋ฐ์ํ ์ ์๋๋ก ํฉ๋๋ค.
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์์กด์ ์ฐ๊ธฐ์ ๋ํด์๋ ์์๋ฅผ ์ก์์ค๋๋ค:
- CPU 1 CPU 2
- =============== ===============
- { A == 1, B == 2, C = 3, P == &A, Q == &C }
- B = 4;
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(P, &B);
- Q = READ_ONCE(P);
- <๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด>
- *Q = 5;
- ์ด ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ Q ๋ก์ ์ฝ๊ธฐ๊ฐ *Q ๋ก์ ์คํ ์ด์ ์์๋ฅผ ๋ง์ถ๊ฒ
- ํด์ค๋๋ค. ์ด๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ง์ต๋๋ค:
- (Q == &B) && (B == 4)
- ์ด๋ฐ ํจํด์ ๋๋ฌผ๊ฒ ์ฌ์ฉ๋์ด์ผ ํจ์ ์์ ๋์๊ธฐ ๋ฐ๋๋๋ค. ๋ฌด์๋ณด๋ค๋, ์์กด์ฑ
- ์์ ๊ท์น์ ์๋๋ ์ฐ๊ธฐ ์์
์ -์๋ฐฉ- ํด์ ๊ทธ๋ก ์ธํด ๋ฐ์ํ๋ ๋น์ผ ์บ์ ๋ฏธ์ค๋
- ์์ ๋ ค๋ ๊ฒ์
๋๋ค. ์ด ํจํด์ ๋๋ฌผ๊ฒ ๋ฐ์ํ๋ ์๋ฌ ์กฐ๊ฑด ๊ฐ์๊ฒ๋ค์ ๊ธฐ๋กํ๋๋ฐ
- ์ฌ์ฉ๋ ์ ์๊ณ , ์ด๋ ๊ฒ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํด ์์๋ฅผ ์งํค๊ฒ ํจ์ผ๋ก์จ ๊ทธ๋ฐ ๊ธฐ๋ก์ด
- ์ฌ๋ผ์ง๋ ๊ฒ์ ๋ง์ต๋๋ค.
- [!] ์๋นํ ๋น์ง๊ด์ ์ธ ์ด ์ํฉ์ ๋ถ๋ฆฌ๋ ์บ์๋ฅผ ๊ฐ์ง ๊ธฐ๊ณ, ์๋ฅผ ๋ค์ด ํ ์บ์
- ๋ฑ
ํฌ๊ฐ ์ง์๋ฒ ์บ์ ๋ผ์ธ์ ์ฒ๋ฆฌํ๊ณ ๋ค๋ฅธ ๋ฑ
ํฌ๋ ํ์๋ฒ ์บ์ ๋ผ์ธ์ ์ฒ๋ฆฌํ๋ ๊ธฐ๊ณ
- ๋ฑ์์ ๊ฐ์ฅ ์ ๋ฐ์ํฉ๋๋ค. ํฌ์ธํฐ P ๋ ํ์ ๋ฒํธ์ ์บ์ ๋ผ์ธ์ ์๊ณ , ๋ณ์ B ๋
- ์ง์ ๋ฒํธ ์บ์ ๋ผ์ธ์ ์๋ค๊ณ ์๊ฐํด ๋ด
์๋ค. ๊ทธ๋ฐ ์ํ์์ ์ฝ๊ธฐ ์์
์ ํ๋ CPU
- ์ ์ง์๋ฒ ๋ฑ
ํฌ๋ ํ ์ผ์ด ์์ฌ ๋งค์ฐ ๋ฐ์์ง๋ง ํ์๋ฒ ๋ฑ
ํฌ๋ ํ ์ผ์ด ์์ด ์๋ฌด
- ์ผ๋ ํ์ง ์๊ณ ์์๋ค๋ฉด, ํฌ์ธํฐ P ๋ ์ ๊ฐ (&B) ์, ๊ทธ๋ฆฌ๊ณ ๋ณ์ B ๋ ์๋ ๊ฐ
- (2) ์ ๊ฐ์ง๊ณ ์๋ ์ํ๊ฐ ๋ณด์ฌ์ง ์๋ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ๋งค์ฐ ์ค์ํ๋ฐ, ์๋ฅผ ๋ค์ด RCU ์์คํ
์์ ๊ทธ๋ ์ต๋๋ค.
- include/linux/rcupdate.h ์ rcu_assign_pointer() ์ rcu_dereference() ๋ฅผ
- ์ฐธ๊ณ ํ์ธ์. ์ฌ๊ธฐ์ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ RCU ๋ก ๊ด๋ฆฌ๋๋ ํฌ์ธํฐ์ ํ๊ฒ์ ํ์ฌ
- ํ๊ฒ์์ ์์ ๋ ์๋ก์ด ํ๊ฒ์ผ๋ก ๋ฐ๊พธ๋ ์์
์์ ์๋ก ์์ ๋ ํ๊ฒ์ด ์ด๊ธฐํ๊ฐ
- ์๋ฃ๋์ง ์์ ์ฑ๋ก ๋ณด์ฌ์ง๋ ์ผ์ด ์ผ์ด๋์ง ์๊ฒ ํด์ค๋๋ค.
- ๋ ๋ง์ ์๋ฅผ ์ํด์ "์บ์ ์ผ๊ด์ฑ" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- ์ปจํธ๋กค ์์กด์ฑ
- -------------
- ๋ก๋-๋ก๋ ์ปจํธ๋กค ์์กด์ฑ์ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ง์ผ๋ก๋ ์ ํํ ๋์ํ ์๊ฐ
- ์์ด์ ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ํ์๋ก ํฉ๋๋ค. ์๋์ ์ฝ๋๋ฅผ ๋ด
์๋ค:
- q = READ_ONCE(a);
- if (q) {
- <๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด> /* BUG: No data dependency!!! */
- p = READ_ONCE(b);
- }
- ์ด ์ฝ๋๋ ์ํ๋ ๋๋ก์ ํจ๊ณผ๋ฅผ ๋ด์ง ๋ชปํ ์ ์๋๋ฐ, ์ด ์ฝ๋์๋ ๋ฐ์ดํฐ ์์กด์ฑ์ด
- ์๋๋ผ ์ปจํธ๋กค ์์กด์ฑ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ผ๋ก, ์ด๋ฐ ์ํฉ์์ CPU ๋ ์คํ ์๋๋ฅผ ๋
- ๋น ๋ฅด๊ฒ ํ๊ธฐ ์ํด ๋ถ๊ธฐ ์กฐ๊ฑด์ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ๊ณ ์ฝ๋๋ฅผ ์ฌ๋ฐฐ์น ํ ์ ์์ด์ ๋ค๋ฅธ
- CPU ๋ b ๋ก๋ถํฐ์ ๋ก๋ ์คํผ๋ ์ด์
์ด a ๋ก๋ถํฐ์ ๋ก๋ ์คํผ๋ ์ด์
๋ณด๋ค ๋จผ์ ๋ฐ์ํ
- ๊ฑธ๋ก ์ธ์ํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ ์ ๋ง๋ก ํ์ํ๋ ๊ฑด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- q = READ_ONCE(a);
- if (q) {
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- p = READ_ONCE(b);
- }
- ํ์ง๋ง, ์คํ ์ด ์คํผ๋ ์ด์
์ ์์ธก์ ์ผ๋ก ์ํ๋์ง ์์ต๋๋ค. ์ฆ, ๋ค์ ์์์์
- ๊ฐ์ด ๋ก๋-์คํ ์ด ์ปจํธ๋กค ์์กด์ฑ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ ์์๊ฐ -์ง์ผ์ง๋ค-๋
- ์๋ฏธ์
๋๋ค.
- q = READ_ONCE(a);
- if (q) {
- WRITE_ONCE(b, p);
- }
- ์ปจํธ๋กค ์์กด์ฑ์ ๋ณดํต ๋ค๋ฅธ ํ์
์ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ ์ง์ ๋ง์ถฐ ์ฌ์ฉ๋ฉ๋๋ค. ๊ทธ๋ ๋ค๊ณค
- ํ๋, READ_ONCE() ๋ ๋ฐ๋์ ์ฌ์ฉํด์ผ ํจ์ ๋ถ๋ ๋ช
์ฌํ์ธ์! READ_ONCE() ๊ฐ
- ์๋ค๋ฉด, ์ปดํ์ผ๋ฌ๊ฐ 'a' ๋ก๋ถํฐ์ ๋ก๋๋ฅผ 'a' ๋ก๋ถํฐ์ ๋๋ค๋ฅธ ๋ก๋์, 'b' ๋ก์
- ์คํ ์ด๋ฅผ 'b' ๋ก์ ๋๋ค๋ฅธ ์คํ ์ด์ ์กฐํฉํด ๋ฒ๋ ค ๋งค์ฐ ๋น์ง๊ด์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์
- ์์ต๋๋ค.
- ์ด๊ฑธ๋ก ๋์ด ์๋๊ฒ, ์ปดํ์ผ๋ฌ๊ฐ ๋ณ์ 'a' ์ ๊ฐ์ด ํญ์ 0์ด ์๋๋ผ๊ณ ์ฆ๋ช
ํ ์
- ์๋ค๋ฉด, ์์ ์์์ "if" ๋ฌธ์ ์์ ์ ๋ค์๊ณผ ๊ฐ์ด ์ต์ ํ ํ ์๋ ์์ต๋๋ค:
- q = a;
- b = p; /* BUG: Compiler and CPU can both reorder!!! */
- ๊ทธ๋ฌ๋ READ_ONCE() ๋ฅผ ๋ฐ๋์ ์ฌ์ฉํ์ธ์.
- ๋ค์๊ณผ ๊ฐ์ด "if" ๋ฌธ์ ์๊ฐ๋ ๋ธ๋์น์ ๋ชจ๋ ์กด์ฌํ๋ ๋์ผํ ์คํ ์ด์ ๋ํด ์์๋ฅผ
- ๊ฐ์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ์์ ์ ์์ต๋๋ค:
- q = READ_ONCE(a);
- if (q) {
- barrier();
- WRITE_ONCE(b, p);
- do_something();
- } else {
- barrier();
- WRITE_ONCE(b, p);
- do_something_else();
- }
- ์ํ๊น๊ฒ๋, ํ์ฌ์ ์ปดํ์ผ๋ฌ๋ค์ ๋์ ์ต์ ํ ๋ ๋ฒจ์์๋ ์ด๊ฑธ ๋ค์๊ณผ ๊ฐ์ด
- ๋ฐ๊ฟ๋ฒ๋ฆฝ๋๋ค:
- q = READ_ONCE(a);
- barrier();
- WRITE_ONCE(b, p); /* BUG: No ordering vs. load from a!!! */
- if (q) {
- /* WRITE_ONCE(b, p); -- moved up, BUG!!! */
- do_something();
- } else {
- /* WRITE_ONCE(b, p); -- moved up, BUG!!! */
- do_something_else();
- }
- ์ด์ 'a' ์์์ ๋ก๋์ 'b' ๋ก์ ์คํ ์ด ์ฌ์ด์๋ ์กฐ๊ฑด์ ๊ด๊ณ๊ฐ ์๊ธฐ ๋๋ฌธ์ CPU
- ๋ ์ด๋ค์ ์์๋ฅผ ๋ฐ๊ฟ ์ ์๊ฒ ๋ฉ๋๋ค: ์ด๋ฐ ๊ฒฝ์ฐ์ ์กฐ๊ฑด์ ๊ด๊ณ๋ ๋ฐ๋์
- ํ์ํ๋ฐ, ๋ชจ๋ ์ปดํ์ผ๋ฌ ์ต์ ํ๊ฐ ์ด๋ฃจ์ด์ง๊ณ ๋ ํ์ ์ด์
๋ธ๋ฆฌ ์ฝ๋์์๋
- ๋ง์ฐฌ๊ฐ์ง์
๋๋ค. ๋ฐ๋ผ์, ์ด ์์์ ์์๋ฅผ ์งํค๊ธฐ ์ํด์๋ smp_store_release()
- ์ ๊ฐ์ ๋ช
์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํฉ๋๋ค:
- q = READ_ONCE(a);
- if (q) {
- smp_store_release(&b, p);
- do_something();
- } else {
- smp_store_release(&b, p);
- do_something_else();
- }
- ๋ฐ๋ฉด์ ๋ช
์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ์๋ค๋ฉด, ์ด๋ฐ ๊ฒฝ์ฐ์ ์์๋ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ด
- ์๋ก ๋ค๋ฅผ ๋์๋ง ๋ณด์ฅ๋๋๋ฐ, ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์
๋๋ค:
- q = READ_ONCE(a);
- if (q) {
- WRITE_ONCE(b, p);
- do_something();
- } else {
- WRITE_ONCE(b, r);
- do_something_else();
- }
- ์ฒ์์ READ_ONCE() ๋ ์ปดํ์ผ๋ฌ๊ฐ 'a' ์ ๊ฐ์ ์ฆ๋ช
ํด๋ด๋ ๊ฒ์ ๋ง๊ธฐ ์ํด ์ฌ์ ํ
- ํ์ํฉ๋๋ค.
- ๋ํ, ๋ก์ปฌ ๋ณ์ 'q' ๋ฅผ ๊ฐ์ง๊ณ ํ๋ ์ผ์ ๋ํด ์ฃผ์ํด์ผ ํ๋๋ฐ, ๊ทธ๋ฌ์ง ์์ผ๋ฉด
- ์ปดํ์ผ๋ฌ๋ ๊ทธ ๊ฐ์ ์ถ์ธกํ๊ณ ๋๋ค์ ํ์ํ ์กฐ๊ฑด๊ด๊ณ๋ฅผ ์์ ๋ฒ๋ฆด ์ ์์ต๋๋ค.
- ์๋ฅผ ๋ค๋ฉด:
- q = READ_ONCE(a);
- if (q % MAX) {
- WRITE_ONCE(b, p);
- do_something();
- } else {
- WRITE_ONCE(b, r);
- do_something_else();
- }
- ๋ง์ฝ MAX ๊ฐ 1 ๋ก ์ ์๋ ์์๋ผ๋ฉด, ์ปดํ์ผ๋ฌ๋ (q % MAX) ๋ 0์ด๋ ๊ฒ์ ์์์ฑ๊ณ ,
- ์์ ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ๋ฐ๊ฟ๋ฒ๋ฆด ์ ์์ต๋๋ค:
- q = READ_ONCE(a);
- WRITE_ONCE(b, p);
- do_something_else();
- ์ด๋ ๊ฒ ๋๋ฉด, CPU ๋ ๋ณ์ 'a' ๋ก๋ถํฐ์ ๋ก๋์ ๋ณ์ 'b' ๋ก์ ์คํ ์ด ์ฌ์ด์ ์์๋ฅผ
- ์ง์ผ์ค ํ์๊ฐ ์์ด์ง๋๋ค. barrier() ๋ฅผ ์ถ๊ฐํด ํด๊ฒฐํด ๋ณด๊ณ ์ถ๊ฒ ์ง๋ง, ๊ทธ๊ฑด
- ๋์์ด ์๋ฉ๋๋ค. ์กฐ๊ฑด ๊ด๊ณ๋ ์ฌ๋ผ์ก๊ณ , barrier() ๋ ์ด๋ฅผ ๋๋๋ฆฌ์ง ๋ชปํฉ๋๋ค.
- ๋ฐ๋ผ์, ์ด ์์๋ฅผ ์ง์ผ์ผ ํ๋ค๋ฉด, MAX ๊ฐ 1 ๋ณด๋ค ํฌ๋ค๋ ๊ฒ์, ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์
- ์ฌ์ฉํด ๋ถ๋ช
ํ ํด์ผ ํฉ๋๋ค:
- q = READ_ONCE(a);
- BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
- if (q % MAX) {
- WRITE_ONCE(b, p);
- do_something();
- } else {
- WRITE_ONCE(b, r);
- do_something_else();
- }
- 'b' ๋ก์ ์คํ ์ด๋ค์ ์ฌ์ ํ ์๋ก ๋ค๋ฆ์ ์์๋์ธ์. ๋ง์ฝ ๊ทธ๊ฒ๋ค์ด ๋์ผํ๋ฉด,
- ์์์ ์ด์ผ๊ธฐํ๋ฏ, ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ 'if' ๋ฌธ ๋ฐ๊นฅ์ผ๋ก
- ๋์ง์ด๋ผ ์ ์์ต๋๋ค.
- ๋ํ ์ด์ง ์กฐ๊ฑด๋ฌธ ํ๊ฐ์ ๋๋ฌด ์์กดํ์ง ์๋๋ก ์กฐ์ฌํด์ผ ํฉ๋๋ค. ๋ค์์ ์๋ฅผ
- ๋ด
์๋ค:
- q = READ_ONCE(a);
- if (q || 1 > 0)
- WRITE_ONCE(b, 1);
- ์ฒซ๋ฒ์งธ ์กฐ๊ฑด๋ง์ผ๋ก๋ ๋ธ๋์น ์กฐ๊ฑด ์ ์ฒด๋ฅผ ๊ฑฐ์ง์ผ๋ก ๋ง๋ค ์ ์๊ณ ๋๋ฒ์งธ ์กฐ๊ฑด์ ํญ์
- ์ฐธ์ด๊ธฐ ๋๋ฌธ์, ์ปดํ์ผ๋ฌ๋ ์ด ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ๊ฟ์ ์ปจํธ๋กค ์์กด์ฑ์ ์์ ๋ฒ๋ฆด
- ์ ์์ต๋๋ค:
- q = READ_ONCE(a);
- WRITE_ONCE(b, 1);
- ์ด ์๋ ์ปดํ์ผ๋ฌ๊ฐ ์ฝ๋๋ฅผ ์ถ์ธก์ผ๋ก ์์ ํ ์ ์๋๋ก ๋ถ๋ช
ํ ํด์ผ ํ๋ค๋ ์ ์
- ๊ฐ์กฐํฉ๋๋ค. ์กฐ๊ธ ๋ ์ผ๋ฐ์ ์ผ๋ก ๋งํด์, READ_ONCE() ๋ ์ปดํ์ผ๋ฌ์๊ฒ ์ฃผ์ด์ง ๋ก๋
- ์คํผ๋ ์ด์
์ ์ํ ์ฝ๋๋ฅผ ์ ๋ง๋ก ๋ง๋ค๋๋ก ํ์ง๋ง, ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ๋ ๊ฒ ๋ง๋ค์ด์ง
- ์ฝ๋์ ์ํ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ๋๋ก ๊ฐ์ ํ์ง๋ ์์ต๋๋ค.
- ๋ง์ง๋ง์ผ๋ก, ์ปจํธ๋กค ์์กด์ฑ์ ์ดํ์ฑ (transitivity) ์ ์ ๊ณตํ์ง -์์ต๋๋ค-. ์ด๊ฑด
- x ์ y ๊ฐ ๋ ๋ค 0 ์ด๋ผ๋ ์ด๊ธฐ๊ฐ์ ๊ฐ์ก๋ค๋ ๊ฐ์ ํ์ ๋๊ฐ์ ์์ ๋ก
- ๋ณด์ด๊ฒ ์ต๋๋ค:
- CPU 0 CPU 1
- ======================= =======================
- r1 = READ_ONCE(x); r2 = READ_ONCE(y);
- if (r1 > 0) if (r2 > 0)
- WRITE_ONCE(y, 1); WRITE_ONCE(x, 1);
- assert(!(r1 == 1 && r2 == 1));
- ์ด ๋ CPU ์์ ์์ assert() ์ ์กฐ๊ฑด์ ํญ์ ์ฐธ์ผ ๊ฒ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ , ๋ง์ฝ ์ปจํธ๋กค
- ์์กด์ฑ์ด ์ดํ์ฑ์ (์ค์ ๋ก๋ ๊ทธ๋ฌ์ง ์์ง๋ง) ๋ณด์ฅํ๋ค๋ฉด, ๋ค์์ CPU ๊ฐ ์ถ๊ฐ๋์ด๋
- ์๋์ assert() ์กฐ๊ฑด์ ์ฐธ์ด ๋ ๊ฒ์
๋๋ค:
- CPU 2
- =====================
- WRITE_ONCE(x, 2);
- assert(!(r1 == 2 && r2 == 1 && x == 2)); /* FAILS!!! */
- ํ์ง๋ง ์ปจํธ๋กค ์์กด์ฑ์ ์ดํ์ฑ์ ์ ๊ณตํ์ง -์๊ธฐ- ๋๋ฌธ์, ์ธ๊ฐ์ CPU ์์ ๊ฐ ์คํ
- ์๋ฃ๋ ํ์ ์์ assert() ์ ์กฐ๊ฑด์ ๊ฑฐ์ง์ผ๋ก ํ๊ฐ๋ ์ ์์ต๋๋ค. ์ธ๊ฐ์ CPU
- ์์ ๊ฐ ์์๋ฅผ ์งํค๊ธธ ์ํ๋ค๋ฉด, CPU 0 ์ CPU 1 ์ฝ๋์ ๋ก๋์ ์คํ ์ด ์ฌ์ด, "if"
- ๋ฌธ ๋ฐ๋ก ๋ค์์ smp_mb()๋ฅผ ๋ฃ์ด์ผ ํฉ๋๋ค. ๋ ๋์๊ฐ์, ์ต์ด์ ๋ CPU ์์ ๋
- ๋งค์ฐ ์ํํ๋ฏ๋ก ์ฌ์ฉ๋์ง ์์์ผ ํฉ๋๋ค.
- ์ด ๋๊ฐ์ ์์ ๋ ๋ค์ ๋
ผ๋ฌธ:
- http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf ์
- ์ด ์ฌ์ดํธ: https://www.cl.cam.ac.uk/~pes20/ppcmem/index.html ์ ๋์จ LB ์ WWC
- ๋ฆฌํธ๋จธ์ค ํ
์คํธ์
๋๋ค.
- ์์ฝํ์๋ฉด:
- (*) ์ปจํธ๋กค ์์กด์ฑ์ ์์ ๋ก๋๋ค์ ๋ค์ ์คํ ์ด๋ค์ ๋ํด ์์๋ฅผ ๋ง์ถฐ์ค๋๋ค.
- ํ์ง๋ง, ๊ทธ ์ธ์ ์ด๋ค ์์๋ ๋ณด์ฅํ์ง -์์ต๋๋ค-: ์์ ๋ก๋์ ๋ค์ ๋ก๋๋ค
- ์ฌ์ด์๋, ์์ ์คํ ์ด์ ๋ค์ ์คํ ์ด๋ค ์ฌ์ด์๋์. ์ด๋ฐ ๋ค๋ฅธ ํํ์
- ์์๊ฐ ํ์ํ๋ค๋ฉด smp_rmb() ๋ smp_wmb()๋ฅผ, ๋๋, ์์ ์คํ ์ด๋ค๊ณผ ๋ค์
- ๋ก๋๋ค ์ฌ์ด์ ์์๋ฅผ ์ํด์๋ smp_mb() ๋ฅผ ์ฌ์ฉํ์ธ์.
- (*) "if" ๋ฌธ์ ์๊ฐ๋ ๋ธ๋์น๊ฐ ๊ฐ์ ๋ณ์์์ ๋์ผํ ์คํ ์ด๋ก ์์ํ๋ค๋ฉด, ๊ทธ
- ์คํ ์ด๋ค์ ๊ฐ ์คํ ์ด ์์ smp_mb() ๋ฅผ ๋ฃ๊ฑฐ๋ smp_store_release() ๋ฅผ
- ์ฌ์ฉํด์ ์คํ ์ด๋ฅผ ํ๋ ์์ผ๋ก ์์๋ฅผ ๋ง์ถฐ์ค์ผ ํฉ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ
- ์ํด "if" ๋ฌธ์ ์๊ฐ๋ ๋ธ๋์น์ ์์ ์ง์ ์ barrier() ๋ฅผ ๋ฃ๋ ๊ฒ๋ง์ผ๋ก๋
- ์ถฉ๋ถํ ํด๊ฒฐ์ด ๋์ง ์๋๋ฐ, ์ด๋ ์์ ์์์ ๋ณธ๊ฒ๊ณผ ๊ฐ์ด, ์ปดํ์ผ๋ฌ์
- ์ต์ ํ๋ barrier() ๊ฐ ์๋ฏธํ๋ ๋ฐ๋ฅผ ์งํค๋ฉด์๋ ์ปจํธ๋กค ์์กด์ฑ์ ์์์ํฌ
- ์ ์๊ธฐ ๋๋ฌธ์ด๋ผ๋ ์ ์ ๋ถ๋ ์์๋์๊ธฐ ๋ฐ๋๋๋ค.
- (*) ์ปจํธ๋กค ์์กด์ฑ์ ์์ ๋ก๋์ ๋ค์ ์คํ ์ด ์ฌ์ด์ ์ต์ ํ๋์, ์คํ
- ์์ ์์์ ์กฐ๊ฑด๊ด๊ณ๋ฅผ ํ์๋ก ํ๋ฉฐ, ์ด ์กฐ๊ฑด๊ด๊ณ๋ ์์ ๋ก๋์ ๊ด๊ณ๋์ด์ผ
- ํฉ๋๋ค. ๋ง์ฝ ์ปดํ์ผ๋ฌ๊ฐ ์กฐ๊ฑด ๊ด๊ณ๋ฅผ ์ต์ ํ๋ก ์์จ์ ์๋ค๋ฉด, ์์๋
- ์ต์ ํ๋ก ์์ ๋ฒ๋ ธ์ ๊ฒ๋๋ค. READ_ONCE() ์ WRITE_ONCE() ์ ์ฃผ์ ๊น์
- ์ฌ์ฉ์ ์ฃผ์ด์ง ์กฐ๊ฑด ๊ด๊ณ๋ฅผ ์ ์งํ๋๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- (*) ์ปจํธ๋กค ์์กด์ฑ์ ์ํด์ ์ปดํ์ผ๋ฌ๊ฐ ์กฐ๊ฑด๊ด๊ณ๋ฅผ ์์ ๋ฒ๋ฆฌ๋ ๊ฒ์ ๋ง์์ผ
- ํฉ๋๋ค. ์ฃผ์ ๊น์ READ_ONCE() ๋ atomic{,64}_read() ์ ์ฌ์ฉ์ด ์ปจํธ๋กค
- ์์กด์ฑ์ด ์ฌ๋ผ์ง์ง ์๊ฒ ํ๋๋ฐ ๋์์ ์ค ์ ์์ต๋๋ค. ๋ ๋ง์ ์ ๋ณด๋ฅผ
- ์ํด์ "์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด" ์น์
์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
- (*) ์ปจํธ๋กค ์์กด์ฑ์ ๋ณดํต ๋ค๋ฅธ ํ์
์ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ ์ง์ ๋ง์ถฐ ์ฌ์ฉ๋ฉ๋๋ค.
- (*) ์ปจํธ๋กค ์์กด์ฑ์ ์ดํ์ฑ์ ์ ๊ณตํ์ง -์์ต๋๋ค-. ์ดํ์ฑ์ด ํ์ํ๋ค๋ฉด,
- smp_mb() ๋ฅผ ์ฌ์ฉํ์ธ์.
- SMP ๋ฐฐ๋ฆฌ์ด ์ง๋ง์ถ๊ธฐ
- --------------------
- CPU ๊ฐ ์ํธ์์ฉ์ ๋ค๋ฃฐ ๋์ ์ผ๋ถ ํ์
์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ํญ์ ์ง์ ๋ง์ถฐ
- ์ฌ์ฉ๋์ด์ผ ํฉ๋๋ค. ์ ์ ํ๊ฒ ์ง์ ๋ง์ถ์ง ์์ ์ฝ๋๋ ์ฌ์ค์ ์๋ฌ์ ๊ฐ๊น์ต๋๋ค.
- ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๋ค์ ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๋ผ๋ฆฌ๋ ์ง์ ๋ง์ถ์ง๋ง ์ดํ์ฑ์ด ์๋ ๋๋ถ๋ถ์ ๋ค๋ฅธ
- ํ์
์ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ๋ ์ง์ ๋ง์ถฅ๋๋ค. ACQUIRE ๋ฐฐ๋ฆฌ์ด๋ RELEASE ๋ฐฐ๋ฆฌ์ด์ ์ง์
- ๋ง์ถฅ๋๋ค๋ง, ๋ ๋ค ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๋ฅผ ํฌํจํด ๋ค๋ฅธ ๋ฐฐ๋ฆฌ์ด๋ค๊ณผ๋ ์ง์ ๋ง์ถ ์ ์์ต๋๋ค.
- ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์ปจํธ๋กค ์์กด์ฑ, ACQUIRE ๋ฐฐ๋ฆฌ์ด, RELEASE
- ๋ฐฐ๋ฆฌ์ด, ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด, ๋๋ ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด์ ์ง์ ๋ง์ถฅ๋๋ค. ๋น์ทํ๊ฒ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋
- ์ปจํธ๋กค ์์กด์ฑ, ๋๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ACQUIRE ๋ฐฐ๋ฆฌ์ด,
- RELEASE ๋ฐฐ๋ฆฌ์ด, ๋๋ ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด์ ์ง์ ๋ง์ถ๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- CPU 1 CPU 2
- =============== ===============
- WRITE_ONCE(a, 1);
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(b, 2); x = READ_ONCE(b);
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- y = READ_ONCE(a);
- ๋๋:
- CPU 1 CPU 2
- =============== ===============================
- a = 1;
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(b, &a); x = READ_ONCE(b);
- <๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด>
- y = *x;
- ๋๋:
- CPU 1 CPU 2
- =============== ===============================
- r1 = READ_ONCE(y);
- <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(y, 1); if (r2 = READ_ONCE(x)) {
- <๋ฌต์์ ์ปจํธ๋กค ์์กด์ฑ>
- WRITE_ONCE(y, 1);
- }
- assert(r1 == 0 || r2 == 0);
- ๊ธฐ๋ณธ์ ์ผ๋ก, ์ฌ๊ธฐ์์ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ "๋ ์ํ๋" ํ์
์ผ ์ ์์ด๋ ํญ์ ์กด์ฌํด์ผ
- ํฉ๋๋ค.
- [!] ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด ์์ ์คํ ์ด ์คํผ๋ ์ด์
์ ์ผ๋ฐ์ ์ผ๋ก ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ
- ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ก๋ ์คํผ๋ ์ด์
๊ณผ ๋งค์น๋ ๊ฒ์ด๊ณ , ๋ฐ๋๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค:
- CPU 1 CPU 2
- =================== ===================
- WRITE_ONCE(a, 1); }---- --->{ v = READ_ONCE(c);
- WRITE_ONCE(b, 2); } \ / { w = READ_ONCE(d);
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด> \ <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- WRITE_ONCE(c, 3); } / \ { x = READ_ONCE(a);
- WRITE_ONCE(d, 4); }---- --->{ y = READ_ONCE(b);
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ํ์ค์ ์
- -------------------------
- ์ฒซ์งธ, ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ ๋ถ๋ถ์ ์์ ์ธ์ฐ๊ธฐ๋ก ๋์ํฉ๋๋ค.
- ์๋์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ๋ณด์ธ์:
- CPU 1
- =======================
- STORE A = 1
- STORE B = 2
- STORE C = 3
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE D = 4
- STORE E = 5
- ์ด ์ด๋ฒคํธ ์ํ์ค๋ ๋ฉ๋ชจ๋ฆฌ ์ผ๊ด์ฑ ์์คํ
์ ์์๋ผ๋ฆฌ์ ์์๊ฐ ์กด์ฌํ์ง ์๋ ์งํฉ
- { STORE A, STORE B, STORE C } ๊ฐ ์ญ์ ์์๋ผ๋ฆฌ์ ์์๊ฐ ์กด์ฌํ์ง ์๋ ์งํฉ
- { STORE D, STORE E } ๋ณด๋ค ๋จผ์ ์ผ์ด๋ ๊ฒ์ผ๋ก ์์คํ
์ ๋๋จธ์ง ์์๋ค์ ๋ณด์ด๋๋ก
- ์ ๋ฌ๋ฉ๋๋ค:
- +-------+ : :
- | | +------+
- | |------>| C=3 | } /\
- | | : +------+ }----- \ -----> ์์คํ
์ ๋๋จธ์ง ์์์
- | | : | A=1 | } \/ ๋ณด์ฌ์ง ์ ์๋ ์ด๋ฒคํธ๋ค
- | | : +------+ }
- | CPU 1 | : | B=2 | }
- | | +------+ }
- | | wwwwwwwwwwwwwwww } <--- ์ฌ๊ธฐ์ ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐฐ๋ฆฌ์ด ์์
- | | +------+ } ๋ชจ๋ ์คํ ์ด๊ฐ ๋ฐฐ๋ฆฌ์ด ๋ค์ ์คํ ์ด
- | | : | E=5 | } ์ ์ ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ์ ๋ฌ๋๋๋ก
- | | : +------+ } ํฉ๋๋ค
- | |------>| D=4 | }
- | | +------+
- +-------+ : :
- |
- | CPU 1 ์ ์ํด ๋ฉ๋ชจ๋ฆฌ ์์คํ
์ ์ ๋ฌ๋๋
- | ์ผ๋ จ์ ์คํ ์ด ์คํผ๋ ์ด์
๋ค
- V
- ๋์งธ, ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ ์์กด์ ๋ก๋ ์คํผ๋ ์ด์
๋ค์ ๋ถ๋ถ์ ์์
- ์ธ์ฐ๊ธฐ๋ก ๋์ํฉ๋๋ค. ๋ค์ ์ผ๋ จ์ ์ด๋ฒคํธ๋ค์ ๋ณด์ธ์:
- CPU 1 CPU 2
- ======================= =======================
- { B = 7; X = 9; Y = 8; C = &Y }
- STORE A = 1
- STORE B = 2
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE C = &B LOAD X
- STORE D = 4 LOAD C (gets &B)
- LOAD *C (reads B)
- ์ฌ๊ธฐ์ ๋ณ๋ค๋ฅธ ๊ฐ์
์ด ์๋ค๋ฉด, CPU 1 ์ ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด์๋ ๋ถ๊ตฌํ๊ณ CPU 2 ๋ CPU 1
- ์ ์ด๋ฒคํธ๋ค์ ์์ ํ ๋ฌด์์์ ์์๋ก ์ธ์งํ๊ฒ ๋ฉ๋๋ค:
- +-------+ : : : :
- | | +------+ +-------+ | CPU 2 ์ ์ธ์ง๋๋
- | |------>| B=2 |----- --->| Y->8 | | ์
๋ฐ์ดํธ ์ด๋ฒคํธ
- | | : +------+ \ +-------+ | ์ํ์ค
- | CPU 1 | : | A=1 | \ --->| C->&Y | V
- | | +------+ | +-------+
- | | wwwwwwwwwwwwwwww | : :
- | | +------+ | : :
- | | : | C=&B |--- | : : +-------+
- | | : +------+ \ | +-------+ | |
- | |------>| D=4 | ----------->| C->&B |------>| |
- | | +------+ | +-------+ | |
- +-------+ : : | : : | |
- | : : | |
- | : : | CPU 2 |
- | +-------+ | |
- ๋ถ๋ช
ํ ์๋ชป๋ ---> | | B->7 |------>| |
- B ์ ๊ฐ ์ธ์ง (!) | +-------+ | |
- | : : | |
- | +-------+ | |
- X ์ ๋ก๋๊ฐ B ์ ---> \ | X->9 |------>| |
- ์ผ๊ด์ฑ ์ ์ง๋ฅผ \ +-------+ | |
- ์ง์ฐ์ํด ----->| B->2 | +-------+
- +-------+
- : :
- ์์ ์์์, CPU 2 ๋ (B ์ ๊ฐ์ด ๋ ) *C ์ ๊ฐ ์ฝ๊ธฐ๊ฐ C ์ LOAD ๋ค์ ์ด์ด์ง์๋
- B ๊ฐ 7 ์ด๋ผ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ต๋๋ค.
- ํ์ง๋ง, ๋ง์ฝ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๊ฐ C ์ ๋ก๋์ *C (์ฆ, B) ์ ๋ก๋ ์ฌ์ด์
- ์์๋ค๋ฉด:
- CPU 1 CPU 2
- ======================= =======================
- { B = 7; X = 9; Y = 8; C = &Y }
- STORE A = 1
- STORE B = 2
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE C = &B LOAD X
- STORE D = 4 LOAD C (gets &B)
- <๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด>
- LOAD *C (reads B)
- ๋ค์๊ณผ ๊ฐ์ด ๋ฉ๋๋ค:
- +-------+ : : : :
- | | +------+ +-------+
- | |------>| B=2 |----- --->| Y->8 |
- | | : +------+ \ +-------+
- | CPU 1 | : | A=1 | \ --->| C->&Y |
- | | +------+ | +-------+
- | | wwwwwwwwwwwwwwww | : :
- | | +------+ | : :
- | | : | C=&B |--- | : : +-------+
- | | : +------+ \ | +-------+ | |
- | |------>| D=4 | ----------->| C->&B |------>| |
- | | +------+ | +-------+ | |
- +-------+ : : | : : | |
- | : : | |
- | : : | CPU 2 |
- | +-------+ | |
- | | X->9 |------>| |
- | +-------+ | |
- C ๋ก์ ์คํ ์ด ์์ ---> \ ddddddddddddddddd | |
- ๋ชจ๋ ์ด๋ฒคํธ ๊ฒฐ๊ณผ๊ฐ \ +-------+ | |
- ๋ค์ ๋ก๋์๊ฒ ----->| B->2 |------>| |
- ๋ณด์ด๊ฒ ๊ฐ์ ํ๋ค +-------+ | |
- : : +-------+
- ์
์งธ, ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ก๋ ์คํผ๋ ์ด์
๋ค์์ ๋ถ๋ถ์ ์์ ์ธ์ฐ๊ธฐ๋ก ๋์ํฉ๋๋ค.
- ์๋์ ์ผ๋ จ์ ์ด๋ฒคํธ๋ฅผ ๋ด
์๋ค:
- CPU 1 CPU 2
- ======================= =======================
- { A = 0, B = 9 }
- STORE A=1
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE B=2
- LOAD B
- LOAD A
- CPU 1 ์ ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ณค์ง๋ง, ๋ณ๋ค๋ฅธ ๊ฐ์
์ด ์๋ค๋ฉด CPU 2 ๋ CPU 1 ์์ ํํด์ง
- ์ด๋ฒคํธ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฌด์์์ ์์๋ก ์ธ์งํ๊ฒ ๋ฉ๋๋ค.
- +-------+ : : : :
- | | +------+ +-------+
- | |------>| A=1 |------ --->| A->0 |
- | | +------+ \ +-------+
- | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
- | | +------+ | +-------+
- | |------>| B=2 |--- | : :
- | | +------+ \ | : : +-------+
- +-------+ : : \ | +-------+ | |
- ---------->| B->2 |------>| |
- | +-------+ | CPU 2 |
- | | A->0 |------>| |
- | +-------+ | |
- | : : +-------+
- \ : :
- \ +-------+
- ---->| A->1 |
- +-------+
- : :
- ํ์ง๋ง, ๋ง์ฝ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๊ฐ B ์ ๋ก๋์ A ์ ๋ก๋ ์ฌ์ด์ ์กด์ฌํ๋ค๋ฉด:
- CPU 1 CPU 2
- ======================= =======================
- { A = 0, B = 9 }
- STORE A=1
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE B=2
- LOAD B
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- LOAD A
- CPU 1 ์ ์ํด ๋ง๋ค์ด์ง ๋ถ๋ถ์ ์์๊ฐ CPU 2 ์๋ ๊ทธ๋๋ก ์ธ์ง๋ฉ๋๋ค:
- +-------+ : : : :
- | | +------+ +-------+
- | |------>| A=1 |------ --->| A->0 |
- | | +------+ \ +-------+
- | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
- | | +------+ | +-------+
- | |------>| B=2 |--- | : :
- | | +------+ \ | : : +-------+
- +-------+ : : \ | +-------+ | |
- ---------->| B->2 |------>| |
- | +-------+ | CPU 2 |
- | : : | |
- | : : | |
- ์ฌ๊ธฐ์ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ----> \ rrrrrrrrrrrrrrrrr | |
- B ๋ก์ ์คํ ์ด ์ ์ \ +-------+ | |
- ๋ชจ๋ ๊ฒฐ๊ณผ๋ฅผ CPU 2 ์ ---->| A->1 |------>| |
- ๋ณด์ด๋๋ก ํ๋ค +-------+ | |
- : : +-------+
- ๋ ์๋ฒฝํ ์ค๋ช
์ ์ํด, A ์ ๋ก๋๊ฐ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด ์๊ณผ ๋ค์ ์์ผ๋ฉด ์ด๋ป๊ฒ ๋ ์ง
- ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- ======================= =======================
- { A = 0, B = 9 }
- STORE A=1
- <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- STORE B=2
- LOAD B
- LOAD A [first load of A]
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- LOAD A [second load of A]
- A ์ ๋ก๋ ๋๊ฐ๊ฐ ๋ชจ๋ B ์ ๋ก๋ ๋ค์ ์์ง๋ง, ์๋ก ๋ค๋ฅธ ๊ฐ์ ์ป์ด์ฌ ์
- ์์ต๋๋ค:
- +-------+ : : : :
- | | +------+ +-------+
- | |------>| A=1 |------ --->| A->0 |
- | | +------+ \ +-------+
- | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
- | | +------+ | +-------+
- | |------>| B=2 |--- | : :
- | | +------+ \ | : : +-------+
- +-------+ : : \ | +-------+ | |
- ---------->| B->2 |------>| |
- | +-------+ | CPU 2 |
- | : : | |
- | : : | |
- | +-------+ | |
- | | A->0 |------>| 1st |
- | +-------+ | |
- ์ฌ๊ธฐ์ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ----> \ rrrrrrrrrrrrrrrrr | |
- B ๋ก์ ์คํ ์ด ์ ์ \ +-------+ | |
- ๋ชจ๋ ๊ฒฐ๊ณผ๋ฅผ CPU 2 ์ ---->| A->1 |------>| 2nd |
- ๋ณด์ด๋๋ก ํ๋ค +-------+ | |
- : : +-------+
- ํ์ง๋ง CPU 1 ์์์ A ์
๋ฐ์ดํธ๋ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๊ฐ ์๋ฃ๋๊ธฐ ์ ์๋ ๋ณด์ผ ์๋
- ์๊ธด ํฉ๋๋ค:
- +-------+ : : : :
- | | +------+ +-------+
- | |------>| A=1 |------ --->| A->0 |
- | | +------+ \ +-------+
- | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
- | | +------+ | +-------+
- | |------>| B=2 |--- | : :
- | | +------+ \ | : : +-------+
- +-------+ : : \ | +-------+ | |
- ---------->| B->2 |------>| |
- | +-------+ | CPU 2 |
- | : : | |
- \ : : | |
- \ +-------+ | |
- ---->| A->1 |------>| 1st |
- +-------+ | |
- rrrrrrrrrrrrrrrrr | |
- +-------+ | |
- | A->1 |------>| 2nd |
- +-------+ | |
- : : +-------+
- ์ฌ๊ธฐ์ ๋ณด์ฅ๋๋ ๊ฑด, ๋ง์ฝ B ์ ๋ก๋๊ฐ B == 2 ๋ผ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ดค๋ค๋ฉด, A ์์ ๋๋ฒ์งธ
- ๋ก๋๋ ํญ์ A == 1 ์ ๋ณด๊ฒ ๋ ๊ฒ์ด๋ผ๋ ๊ฒ๋๋ค. A ์์ ์ฒซ๋ฒ์งธ ๋ก๋์๋ ๊ทธ๋ฐ
- ๋ณด์ฅ์ด ์์ต๋๋ค; A == 0 ์ด๊ฑฐ๋ A == 1 ์ด๊ฑฐ๋ ๋ ์ค ํ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ฒ ๋ ๊ฒ๋๋ค.
- ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด VS ๋ก๋ ์์ธก
- -------------------------------
- ๋ง์ CPU๋ค์ด ๋ก๋๋ฅผ ์์ธก์ ์ผ๋ก (speculatively) ํฉ๋๋ค: ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์
- ๋ก๋ํด์ผ ํ๊ฒ ๋ ์ง ์์ธก์ ํ๋ค๋ฉด, ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ์ธ์คํธ๋ญ์
์ ์ค์ ๋ก๋
- ์์ง ๋ง๋์ง ์์๋๋ผ๋ ๋ค๋ฅธ ๋ก๋ ์์
์ด ์์ด ๋ฒ์ค (bus) ๊ฐ ์๋ฌด ์ผ๋ ํ๊ณ ์์ง
- ์๋ค๋ฉด, ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํฉ๋๋ค. ์ดํ์ ์ค์ ๋ก๋ ์ธ์คํธ๋ญ์
์ด ์คํ๋๋ฉด CPU ๊ฐ
- ์ด๋ฏธ ๊ทธ ๊ฐ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ก๋ ์ธ์คํธ๋ญ์
์ ์ฆ์ ์๋ฃ๋ฉ๋๋ค.
- ํด๋น CPU ๋ ์ค์ ๋ก๋ ๊ทธ ๊ฐ์ด ํ์์น ์์๋ค๋ ์ฌ์ค์ด ๋์ค์ ๋๋ฌ๋ ์๋ ์๋๋ฐ -
- ํด๋น ๋ก๋ ์ธ์คํธ๋ญ์
์ด ๋ธ๋์น๋ก ์ฐํ๋๊ฑฐ๋ ํ์ ์ ์๊ฒ ์ฃ - , ๊ทธ๋ ๊ฒ ๋๋ฉด ์์
- ์ฝ์ด๋ ๊ฐ์ ๋ฒ๋ฆฌ๊ฑฐ๋ ๋์ค์ ์ฌ์ฉ์ ์ํด ์บ์์ ๋ฃ์ด๋ ์ ์์ต๋๋ค.
- ๋ค์์ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- ======================= =======================
- LOAD B
- DIVIDE } ๋๋๊ธฐ ๋ช
๋ น์ ์ผ๋ฐ์ ์ผ๋ก
- DIVIDE } ๊ธด ์๊ฐ์ ํ์๋ก ํฉ๋๋ค
- LOAD A
- ๋ ์ด๋ ๊ฒ ๋ ์ ์์ต๋๋ค:
- : : +-------+
- +-------+ | |
- --->| B->2 |------>| |
- +-------+ | CPU 2 |
- : :DIVIDE | |
- +-------+ | |
- ๋๋๊ธฐ ํ๋๋ผ ๋ฐ์ ---> --->| A->0 |~~~~ | |
- CPU ๋ A ์ LOAD ๋ฅผ +-------+ ~ | |
- ์์ธกํด์ ์ํํ๋ค : : ~ | |
- : :DIVIDE | |
- : : ~ | |
- ๋๋๊ธฐ๊ฐ ๋๋๋ฉด ---> ---> : : ~-->| |
- CPU ๋ ํด๋น LOAD ๋ฅผ : : | |
- ์ฆ๊ฐ ์๋ฃํ๋ค : : +-------+
- ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋๋ฒ์งธ ๋ก๋ ์ง์ ์ ๋๋๋ค๋ฉด:
- CPU 1 CPU 2
- ======================= =======================
- LOAD B
- DIVIDE
- DIVIDE
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- LOAD A
- ์์ธก์ผ๋ก ์ป์ด์ง ๊ฐ์ ์ฌ์ฉ๋ ๋ฐฐ๋ฆฌ์ด์ ํ์
์ ๋ฐ๋ผ์ ํด๋น ๊ฐ์ด ์ณ์์ง ๊ฒํ ๋๊ฒ
- ๋ฉ๋๋ค. ๋ง์ฝ ํด๋น ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ณํ๊ฐ ์์๋ค๋ฉด, ์์ธก์ผ๋ก ์ป์ด๋์๋ ๊ฐ์ด
- ์ฌ์ฉ๋ฉ๋๋ค:
- : : +-------+
- +-------+ | |
- --->| B->2 |------>| |
- +-------+ | CPU 2 |
- : :DIVIDE | |
- +-------+ | |
- ๋๋๊ธฐ ํ๋๋ผ ๋ฐ์ ---> --->| A->0 |~~~~ | |
- CPU ๋ A ์ LOAD ๋ฅผ +-------+ ~ | |
- ์์ธกํ๋ค : : ~ | |
- : :DIVIDE | |
- : : ~ | |
- : : ~ | |
- rrrrrrrrrrrrrrrr~ | |
- : : ~ | |
- : : ~-->| |
- : : | |
- : : +-------+
- ํ์ง๋ง ๋ค๋ฅธ CPU ์์ ์
๋ฐ์ดํธ๋ ๋ฌดํจํ๊ฐ ์์๋ค๋ฉด, ๊ทธ ์์ธก์ ๋ฌดํจํ๋๊ณ ๊ทธ ๊ฐ์
- ๋ค์ ์ฝํ์ง๋๋ค:
- : : +-------+
- +-------+ | |
- --->| B->2 |------>| |
- +-------+ | CPU 2 |
- : :DIVIDE | |
- +-------+ | |
- ๋๋๊ธฐ ํ๋๋ผ ๋ฐ์ ---> --->| A->0 |~~~~ | |
- CPU ๋ A ์ LOAD ๋ฅผ +-------+ ~ | |
- ์์ธกํ๋ค : : ~ | |
- : :DIVIDE | |
- : : ~ | |
- : : ~ | |
- rrrrrrrrrrrrrrrrr | |
- +-------+ | |
- ์์ธก์ฑ ๋์์ ๋ฌดํจํ ๋๊ณ ---> --->| A->1 |------>| |
- ์
๋ฐ์ดํธ๋ ๊ฐ์ด ๋ค์ ์ฝํ์ง๋ค +-------+ | |
- : : +-------+
- ์ดํ์ฑ
- ------
- ์ดํ์ฑ(transitivity)์ ์ค์ ์ ์ปดํจํฐ ์์คํ
์์ ํญ์ ์ ๊ณต๋์ง๋ ์๋, ์์
- ๋ง์ถ๊ธฐ์ ๋ํ ์๋นํ ์ง๊ด์ ์ธ ๊ฐ๋
์
๋๋ค. ๋ค์์ ์๊ฐ ์ดํ์ฑ์ ๋ณด์ฌ์ค๋๋ค:
- CPU 1 CPU 2 CPU 3
- ======================= ======================= =======================
- { X = 0, Y = 0 }
- STORE X=1 LOAD X STORE Y=1
- <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด> <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด>
- LOAD Y LOAD X
- CPU 2 ์ X ๋ก๋๊ฐ 1์ ๋ฆฌํดํ๊ณ Y ๋ก๋๊ฐ 0์ ๋ฆฌํดํ๋ค๊ณ ํด๋ด
์๋ค. ์ด๋ CPU 2 ์
- X ๋ก๋๊ฐ CPU 1 ์ X ์คํ ์ด ๋ค์ ์ด๋ฃจ์ด์ก๊ณ CPU 2 ์ Y ๋ก๋๋ CPU 3 ์ Y ์คํ ์ด
- ์ ์ ์ด๋ฃจ์ด์ก์์ ์๋ฏธํฉ๋๋ค. ๊ทธ๋ผ "CPU 3 ์ X ๋ก๋๋ 0์ ๋ฆฌํดํ ์ ์๋์?"
- CPU 2 ์ X ๋ก๋๋ CPU 1 ์ ์คํ ์ด ํ์ ์ด๋ฃจ์ด์ก์ผ๋, CPU 3 ์ X ๋ก๋๋ 1์
- ๋ฆฌํดํ๋๊ฒ ์์ฐ์ค๋ฝ์ต๋๋ค. ์ด๋ฐ ์๊ฐ์ด ์ดํ์ฑ์ ํ ์์
๋๋ค: CPU A ์์ ์คํ๋
- ๋ก๋๊ฐ CPU B ์์์ ๊ฐ์ ๋ณ์์ ๋ํ ๋ก๋๋ฅผ ๋ค๋ฐ๋ฅธ๋ค๋ฉด, CPU A ์ ๋ก๋๋ CPU B
- ์ ๋ก๋๊ฐ ๋ด๋์ ๊ฐ๊ณผ ๊ฐ๊ฑฐ๋ ๊ทธ ํ์ ๊ฐ์ ๋ด๋์์ผ ํฉ๋๋ค.
- ๋ฆฌ๋
์ค ์ปค๋์์ ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด์ ์ฌ์ฉ์ ์ดํ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ๋ฐ๋ผ์, ์์ ์์์
- CPU 2 ์ X ๋ก๋๊ฐ 1์, Y ๋ก๋๋ 0์ ๋ฆฌํดํ๋ค๋ฉด, CPU 3 ์ X ๋ก๋๋ ๋ฐ๋์ 1์
- ๋ฆฌํดํฉ๋๋ค.
- ํ์ง๋ง, ์ฝ๊ธฐ๋ ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด์ ๋ํด์๋ ์ดํ์ฑ์ด ๋ณด์ฅ๋์ง -์์ต๋๋ค-. ์๋ฅผ ๋ค์ด,
- ์์ ์์์ CPU 2 ์ ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๊ฐ ์๋์ฒ๋ผ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ก ๋ฐ๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด
- ๋ด
์๋ค:
- CPU 1 CPU 2 CPU 3
- ======================= ======================= =======================
- { X = 0, Y = 0 }
- STORE X=1 LOAD X STORE Y=1
- <์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด> <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด>
- LOAD Y LOAD X
- ์ด ์ฝ๋๋ ์ดํ์ฑ์ ๊ฐ์ง ์์ต๋๋ค: ์ด ์์์๋, CPU 2 ์ X ๋ก๋๊ฐ 1์
- ๋ฆฌํดํ๊ณ , Y ๋ก๋๋ 0์ ๋ฆฌํดํ์ง๋ง CPU 3 ์ X ๋ก๋๊ฐ 0์ ๋ฆฌํดํ๋ ๊ฒ๋ ์์ ํ
- ํฉ๋ฒ์ ์
๋๋ค.
- CPU 2 ์ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๊ฐ ์์ ์ ์ฝ๊ธฐ๋ ์์๋ฅผ ๋ง์ถฐ์ค๋, CPU 1 ์ ์คํ ์ด์์
- ์์๋ฅผ ๋ง์ถฐ์ค๋ค๊ณ ๋ ๋ณด์ฅํ ์ ์๋ค๋๊ฒ ํต์ฌ์
๋๋ค. ๋ฐ๋ผ์, CPU 1 ๊ณผ CPU 2 ๊ฐ
- ๋ฒํผ๋ ์บ์๋ฅผ ๊ณต์ ํ๋ ์์คํ
์์ ์ด ์์ ์ฝ๋๊ฐ ์คํ๋๋ค๋ฉด, CPU 2 ๋ CPU 1 ์ด
- ์ด ๊ฐ์ ์ข ๋นจ๋ฆฌ ์ ๊ทผํ ์ ์์ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ CPU 1 ๊ณผ CPU 2 ์ ์ ๊ทผ์ผ๋ก
- ์กฐํฉ๋ ์์๋ฅผ ๋ชจ๋ CPU ๊ฐ ๋์ํ ์ ์๋๋ก ํ๊ธฐ ์ํด ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํฉ๋๋ค.
- ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๋ "๊ธ๋ก๋ฒ ์ดํ์ฑ"์ ์ ๊ณตํด์, ๋ชจ๋ CPU ๋ค์ด ์คํผ๋ ์ด์
๋ค์ ์์์
- ๋์ํ๊ฒ ํ ๊ฒ์
๋๋ค. ๋ฐ๋ฉด, release-acquire ์กฐํฉ์ "๋ก์ปฌ ์ดํ์ฑ" ๋ง์
- ์ ๊ณตํด์, ํด๋น ์กฐํฉ์ด ์ฌ์ฉ๋ CPU ๋ค๋ง์ด ํด๋น ์ก์ธ์ค๋ค์ ์กฐํฉ๋ ์์์ ๋์ํจ์ด
- ๋ณด์ฅ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์กด๊ฒฝ์ค๋ฐ Herman Hollerith ์ C ์ฝ๋๋ก ๋ณด๋ฉด:
- int u, v, x, y, z;
- void cpu0(void)
- {
- r0 = smp_load_acquire(&x);
- WRITE_ONCE(u, 1);
- smp_store_release(&y, 1);
- }
- void cpu1(void)
- {
- r1 = smp_load_acquire(&y);
- r4 = READ_ONCE(v);
- r5 = READ_ONCE(u);
- smp_store_release(&z, 1);
- }
- void cpu2(void)
- {
- r2 = smp_load_acquire(&z);
- smp_store_release(&x, 1);
- }
- void cpu3(void)
- {
- WRITE_ONCE(v, 1);
- smp_mb();
- r3 = READ_ONCE(u);
- }
- cpu0(), cpu1(), ๊ทธ๋ฆฌ๊ณ cpu2() ๋ smp_store_release()/smp_load_acquire() ์์
- ์ฐ๊ฒฐ์ ํตํ ๋ก์ปฌ ์ดํ์ฑ์ ๋์ฐธํ๊ณ ์์ผ๋ฏ๋ก, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ ๋์ค์ง ์์
- ๊ฒ๋๋ค:
- r0 == 1 && r1 == 1 && r2 == 1
- ๋ ๋์๊ฐ์, cpu0() ์ cpu1() ์ฌ์ด์ release-acquire ๊ด๊ณ๋ก ์ธํด, cpu1() ์
- cpu0() ์ ์ฐ๊ธฐ๋ฅผ ๋ด์ผ๋ง ํ๋ฏ๋ก, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ ์์ ๊ฒ๋๋ค:
- r1 == 1 && r5 == 0
- ํ์ง๋ง, release-acquire ํ๋์ฑ์ ๋์ฐธํ CPU ๋ค์๋ง ์ ์ฉ๋๋ฏ๋ก cpu3() ์๋
- ์ ์ฉ๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๊ฐ๋ฅํฉ๋๋ค:
- r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0
- ๋น์ทํ๊ฒ, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ ๊ฐ๋ฅํฉ๋๋ค:
- r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0 && r5 == 1
- cpu0(), cpu1(), ๊ทธ๋ฆฌ๊ณ cpu2() ๋ ๊ทธ๋ค์ ์ฝ๊ธฐ์ ์ฐ๊ธฐ๋ฅผ ์์๋๋ก ๋ณด๊ฒ ๋์ง๋ง,
- release-acquire ์ฒด์ธ์ ๊ด์ฌ๋์ง ์์ CPU ๋ค์ ๊ทธ ์์์ ์ด๊ฒฌ์ ๊ฐ์ง ์
- ์์ต๋๋ค. ์ด๋ฐ ์ด๊ฒฌ์ smp_load_acquire() ์ smp_store_release() ์ ๊ตฌํ์
- ์ฌ์ฉ๋๋ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ธ์คํธ๋ญ์
๋ค์ ํญ์ ๋ฐฐ๋ฆฌ์ด ์์ ์คํ ์ด๋ค์ ๋ค์
- ๋ก๋๋ค์ ์์ธ์ธ ํ์๋ ์๋ค๋ ์ฌ์ค์์ ๊ธฐ์ธํฉ๋๋ค. ์ด ๋ง์ cpu3() ๋ cpu0() ์
- u ๋ก์ ์คํ ์ด๋ฅผ cpu1() ์ v ๋ก๋ถํฐ์ ๋ก๋ ๋ค์ ์ผ์ด๋ ๊ฒ์ผ๋ก ๋ณผ ์ ์๋ค๋
- ๋ป์
๋๋ค, cpu0() ์ cpu1() ์ ์ด ๋ ์คํผ๋ ์ด์
์ด ์๋๋ ์์๋๋ก ์ผ์ด๋ฌ์์
- ๋ชจ๋ ๋์ํ๋๋ฐ๋ ๋ง์
๋๋ค.
- ํ์ง๋ง, smp_load_acquire() ๋ ๋ง์ ์ด ์๋์ ๋ช
์ฌํ์๊ธฐ ๋ฐ๋๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก,
- ์ด ํจ์๋ ๋จ์ํ ์์ ๊ท์น์ ์งํค๋ฉฐ ์ธ์๋ก๋ถํฐ์ ์ฝ๊ธฐ๋ฅผ ์ํํฉ๋๋ค. ์ด๊ฒ์
- ์ด๋ค ํน์ ํ ๊ฐ์ด ์ฝํ ๊ฒ์ธ์ง๋ ๋ณด์ฅํ์ง -์์ต๋๋ค-. ๋ฐ๋ผ์, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋
- ๊ฐ๋ฅํฉ๋๋ค:
- r0 == 0 && r1 == 0 && r2 == 0 && r5 == 0
- ์ด๋ฐ ๊ฒฐ๊ณผ๋ ์ด๋ค ๊ฒ๋ ์ฌ๋ฐฐ์น ๋์ง ์๋, ์์ฐจ์ ์ผ๊ด์ฑ์ ๊ฐ์ง ๊ฐ์์
- ์์คํ
์์๋ ์ผ์ด๋ ์ ์์์ ๊ธฐ์ตํด ๋์๊ธฐ ๋ฐ๋๋๋ค.
- ๋ค์ ๋งํ์ง๋ง, ๋น์ ์ ์ฝ๋๊ฐ ๊ธ๋ก๋ฒ ์ดํ์ฑ์ ํ์๋ก ํ๋ค๋ฉด, ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด๋ฅผ
- ์ฌ์ฉํ์ญ์์ค.
- ==================
- ๋ช
์์ ์ปค๋ ๋ฐฐ๋ฆฌ์ด
- ==================
- ๋ฆฌ๋
์ค ์ปค๋์ ์๋ก ๋ค๋ฅธ ๋จ๊ณ์์ ๋์ํ๋ ๋ค์ํ ๋ฐฐ๋ฆฌ์ด๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค:
- (*) ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด.
- (*) CPU ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด.
- (*) MMIO ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด.
- ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด
- ---------------
- ๋ฆฌ๋
์ค ์ปค๋์ ์ปดํ์ผ๋ฌ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ฅผ ์ฌ๋ฐฐ์น ํ๋ ๊ฒ์ ๋ง์์ฃผ๋ ๋ช
์์ ์ธ
- ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค:
- barrier();
- ์ด๊ฑด ๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด์
๋๋ค -- barrier() ์ ์ฝ๊ธฐ-์ฝ๊ธฐ ๋ ์ฐ๊ธฐ-์ฐ๊ธฐ ๋ณ์ข
์ ์์ต๋๋ค.
- ํ์ง๋ง, READ_ONCE() ์ WRITE_ONCE() ๋ ํน์ ์ก์ธ์ค๋ค์ ๋ํด์๋ง ๋์ํ๋
- barrier() ์ ์ํ๋ ํํ๋ก ๋ณผ ์ ์์ต๋๋ค.
- barrier() ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ํจ๊ณผ๋ฅผ ๊ฐ์ต๋๋ค:
- (*) ์ปดํ์ผ๋ฌ๊ฐ barrier() ๋ค์ ์ก์ธ์ค๋ค์ด barrier() ์์ ์ก์ธ์ค๋ณด๋ค ์์ผ๋ก
- ์ฌ๋ฐฐ์น๋์ง ๋ชปํ๊ฒ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ ์ฝ๋์ ์ธํฐ๋ฝํธ ๋นํ
- ์ฝ๋ ์ฌ์ด์ ํต์ ์ ์ ์คํ ํ๊ธฐ ์ํด ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- (*) ๋ฃจํ์์, ์ปดํ์ผ๋ฌ๊ฐ ๋ฃจํ ์กฐ๊ฑด์ ์ฌ์ฉ๋ ๋ณ์๋ฅผ ๋งค ์ดํฐ๋ ์ด์
๋ง๋ค
- ๋ฉ๋ชจ๋ฆฌ์์ ๋ก๋ํ์ง ์์๋ ๋๋๋ก ์ต์ ํ ํ๋๊ฑธ ๋ฐฉ์งํฉ๋๋ค.
- READ_ONCE() ์ WRITE_ONCE() ํจ์๋ ์ฑ๊ธ ์ฐ๋ ๋ ์ฝ๋์์๋ ๋ฌธ์ ์์ง๋ง ๋์์ฑ์ด
- ์๋ ์ฝ๋์์๋ ๋ฌธ์ ๊ฐ ๋ ์ ์๋ ๋ชจ๋ ์ต์ ํ๋ฅผ ๋ง์ต๋๋ค. ์ด๋ฐ ๋ฅ์ ์ต์ ํ์
- ๋ํ ์๋ฅผ ๋ช๊ฐ์ง ๋ค์ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- (*) ์ปดํ์ผ๋ฌ๋ ๊ฐ์ ๋ณ์์ ๋ํ ๋ก๋์ ์คํ ์ด๋ฅผ ์ฌ๋ฐฐ์น ํ ์ ์๊ณ , ์ด๋ค
- ๊ฒฝ์ฐ์๋ CPU๊ฐ ๊ฐ์ ๋ณ์๋ก๋ถํฐ์ ๋ก๋๋ค์ ์ฌ๋ฐฐ์นํ ์๋ ์์ต๋๋ค. ์ด๋
- ๋ค์์ ์ฝ๋๊ฐ:
- a[0] = x;
- a[1] = x;
- x ์ ์์ ๊ฐ์ด a[1] ์, ์ ๊ฐ์ด a[0] ์ ์๊ฒ ํ ์ ์๋ค๋ ๋ป์
๋๋ค.
- ์ปดํ์ผ๋ฌ์ CPU๊ฐ ์ด๋ฐ ์ผ์ ๋ชปํ๊ฒ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํด์ผ ํฉ๋๋ค:
- a[0] = READ_ONCE(x);
- a[1] = READ_ONCE(x);
- ์ฆ, READ_ONCE() ์ WRITE_ONCE() ๋ ์ฌ๋ฌ CPU ์์ ํ๋์ ๋ณ์์ ๊ฐํด์ง๋
- ์ก์ธ์ค๋ค์ ์บ์ ์ผ๊ด์ฑ์ ์ ๊ณตํฉ๋๋ค.
- (*) ์ปดํ์ผ๋ฌ๋ ๊ฐ์ ๋ณ์์ ๋ํ ์ฐ์์ ์ธ ๋ก๋๋ค์ ๋ณํฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ
- ๋ณํฉ ์์
์ผ๋ก ์ปดํ์ผ๋ฌ๋ ๋ค์์ ์ฝ๋๋ฅผ:
- while (tmp = a)
- do_something_with(tmp);
- ๋ค์๊ณผ ๊ฐ์ด, ์ฑ๊ธ ์ฐ๋ ๋ ์ฝ๋์์๋ ๋ง์ด ๋์ง๋ง ๊ฐ๋ฐ์์ ์๋์ ์ ํ ๋ง์ง
- ์๋ ๋ฐฉํฅ์ผ๋ก "์ต์ ํ" ํ ์ ์์ต๋๋ค:
- if (tmp = a)
- for (;;)
- do_something_with(tmp);
- ์ปดํ์ผ๋ฌ๊ฐ ์ด๋ฐ ์ง์ ํ์ง ๋ชปํ๊ฒ ํ๋ ค๋ฉด READ_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์:
- while (tmp = READ_ONCE(a))
- do_something_with(tmp);
- (*) ์์ปจ๋ ๋ ์ง์คํฐ ์ฌ์ฉ๋์ด ๋ง์ ์ปดํ์ผ๋ฌ๊ฐ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ ์ง์คํฐ์ ๋ด์ ์
- ์๋ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ ๋ณ์๋ฅผ ๋ค์ ๋ก๋ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ปดํ์ผ๋ฌ๋
- ์์ ์์์ ๋ณ์ 'tmp' ์ฌ์ฉ์ ์ต์ ํ๋ก ์์ ๋ฒ๋ฆด ์ ์์ต๋๋ค:
- while (tmp = a)
- do_something_with(tmp);
- ์ด ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ฑ๊ธ ์ฐ๋ ๋์์๋ ์๋ฒฝํ์ง๋ง ๋์์ฑ์ด ์กด์ฌํ๋
- ๊ฒฝ์ฐ์ ์น๋ช
์ ์ธ ์ฝ๋๋ก ๋ฐ๋ ์ ์์ต๋๋ค:
- while (a)
- do_something_with(a);
- ์๋ฅผ ๋ค์ด, ์ต์ ํ๋ ์ด ์ฝ๋๋ ๋ณ์ a ๊ฐ ๋ค๋ฅธ CPU ์ ์ํด "while" ๋ฌธ๊ณผ
- do_something_with() ํธ์ถ ์ฌ์ด์ ๋ฐ๋์ด do_something_with() ์ 0์ ๋๊ธธ
- ์๋ ์์ต๋๋ค.
- ์ด๋ฒ์๋, ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ๋ฐ ์ง์ ํ๋๊ฑธ ๋ง๊ธฐ ์ํด READ_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์:
- while (tmp = READ_ONCE(a))
- do_something_with(tmp);
- ๋ ์ง์คํฐ๊ฐ ๋ถ์กฑํ ์ํฉ์ ๊ฒช๋ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ tmp ๋ฅผ ์คํ์ ์ ์ฅํด๋ ์๋
- ์์ต๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๋ณ์๋ฅผ ๋ค์ ์ฝ์ด๋ค์ด๋๊ฑด ์ด๋ ๊ฒ ์ ์ฅํด๋๊ณ ํ์ ๋ค์
- ์ฝ์ด๋ค์ด๋๋ฐ ๋๋ ์ค๋ฒํค๋ ๋๋ฌธ์
๋๋ค. ๊ทธ๋ ๊ฒ ํ๋๊ฒ ์ฑ๊ธ ์ฐ๋ ๋
- ์ฝ๋์์๋ ์์ ํ๋ฏ๋ก, ์์ ํ์ง ์์ ๊ฒฝ์ฐ์๋ ์ปดํ์ผ๋ฌ์๊ฒ ์ง์ ์๋ ค์ค์ผ
- ํฉ๋๋ค.
- (*) ์ปดํ์ผ๋ฌ๋ ๊ทธ ๊ฐ์ด ๋ฌด์์ผ์ง ์๊ณ ์๋ค๋ฉด ๋ก๋๋ฅผ ์์ ์ํ ์๋ ์์ต๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ค์์ ์ฝ๋๋ ๋ณ์ 'a' ์ ๊ฐ์ด ํญ์ 0์์ ์ฆ๋ช
ํ ์ ์๋ค๋ฉด:
- while (tmp = a)
- do_something_with(tmp);
- ์ด๋ ๊ฒ ์ต์ ํ ๋์ด๋ฒ๋ฆด ์ ์์ต๋๋ค:
- do { } while (0);
- ์ด ๋ณํ์ ์ฑ๊ธ ์ฐ๋ ๋ ์ฝ๋์์๋ ๋์์ด ๋๋๋ฐ ๋ก๋์ ๋ธ๋์น๋ฅผ ์ ๊ฑฐํ๊ธฐ
- ๋๋ฌธ์
๋๋ค. ๋ฌธ์ ๋ ์ปดํ์ผ๋ฌ๊ฐ 'a' ์ ๊ฐ์ ์
๋ฐ์ดํธ ํ๋๊ฑด ํ์ฌ์ CPU ํ๋
- ๋ฟ์ด๋ผ๋ ๊ฐ์ ์์์ ์ฆ๋ช
์ ํ๋ค๋๋ฐ ์์ต๋๋ค. ๋ง์ฝ ๋ณ์ 'a' ๊ฐ ๊ณต์ ๋์ด
- ์๋ค๋ฉด, ์ปดํ์ผ๋ฌ์ ์ฆ๋ช
์ ํ๋ฆฐ ๊ฒ์ด ๋ ๊ฒ๋๋ค. ์ปดํ์ผ๋ฌ๋ ๊ทธ ์์ ์ด
- ์๊ฐํ๋ ๊ฒ๋งํผ ๋ง์ ๊ฒ์ ์๊ณ ์์ง ๋ชปํจ์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ฆฌ๊ธฐ ์ํด
- READ_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์:
- while (tmp = READ_ONCE(a))
- do_something_with(tmp);
- ํ์ง๋ง ์ปดํ์ผ๋ฌ๋ READ_ONCE() ๋ค์ ๋์ค๋ ๊ฐ์ ๋ํด์๋ ๋๊ธธ์ ๋๊ณ ์์์
- ๊ธฐ์ตํ์ธ์. ์๋ฅผ ๋ค์ด, ๋ค์์ ์ฝ๋์์ MAX ๋ ์ ์ฒ๋ฆฌ๊ธฐ ๋งคํฌ๋ก๋ก, 1์ ๊ฐ์
- ๊ฐ๋๋ค๊ณ ํด๋ด
์๋ค:
- while ((tmp = READ_ONCE(a)) % MAX)
- do_something_with(tmp);
- ์ด๋ ๊ฒ ๋๋ฉด ์ปดํ์ผ๋ฌ๋ MAX ๋ฅผ ๊ฐ์ง๊ณ ์ํ๋๋ "%" ์คํผ๋ ์ดํฐ์ ๊ฒฐ๊ณผ๊ฐ ํญ์
- 0์ด๋ผ๋ ๊ฒ์ ์๊ฒ ๋๊ณ , ์ปดํ์ผ๋ฌ๊ฐ ์ฝ๋๋ฅผ ์ค์ง์ ์ผ๋ก๋ ์กด์ฌํ์ง ์๋
- ๊ฒ์ฒ๋ผ ์ต์ ํ ํ๋ ๊ฒ์ด ํ์ฉ๋์ด ๋ฒ๋ฆฝ๋๋ค. ('a' ๋ณ์์ ๋ก๋๋ ์ฌ์ ํ
- ํํด์ง ๊ฒ๋๋ค.)
- (*) ๋น์ทํ๊ฒ, ์ปดํ์ผ๋ฌ๋ ๋ณ์๊ฐ ์ ์ฅํ๋ ค ํ๋ ๊ฐ์ ์ด๋ฏธ ๊ฐ์ง๊ณ ์๋ค๋ ๊ฒ์
- ์๋ฉด ์คํ ์ด ์์ฒด๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ์ด๋ฒ์๋, ์ปดํ์ผ๋ฌ๋ ํ์ฌ์ CPU
- ๋ง์ด ๊ทธ ๋ณ์์ ๊ฐ์ ์ฐ๋ ์ค๋ก์ง ํ๋์ ์กด์ฌ๋ผ๊ณ ์๊ฐํ์ฌ ๊ณต์ ๋ ๋ณ์์
- ๋ํด์๋ ์๋ชป๋ ์ผ์ ํ๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ์์ ์
- ์์ต๋๋ค:
- a = 0;
- ... ๋ณ์ a ์ ์คํ ์ด๋ฅผ ํ์ง ์๋ ์ฝ๋ ...
- a = 0;
- ์ปดํ์ผ๋ฌ๋ ๋ณ์ 'a' ์ ๊ฐ์ ์ด๋ฏธ 0์ด๋ผ๋ ๊ฒ์ ์๊ณ , ๋ฐ๋ผ์ ๋๋ฒ์งธ ์คํ ์ด๋ฅผ
- ์ญ์ ํ ๊ฒ๋๋ค. ๋ง์ฝ ๋ค๋ฅธ CPU ๊ฐ ๊ทธ ์ฌ์ด ๋ณ์ 'a' ์ ๋ค๋ฅธ ๊ฐ์ ์ผ๋ค๋ฉด
- ํฉ๋นํ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฒ๋๋ค.
- ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ๋ฐ ์๋ชป๋ ์ถ์ธก์ ํ์ง ์๋๋ก WRITE_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์:
- WRITE_ONCE(a, 0);
- ... ๋ณ์ a ์ ์คํ ์ด๋ฅผ ํ์ง ์๋ ์ฝ๋ ...
- WRITE_ONCE(a, 0);
- (*) ์ปดํ์ผ๋ฌ๋ ํ์ง ๋ง๋ผ๊ณ ํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ ์ฌ๋ฐฐ์น ํ ์
- ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์์ ํ๋ก์ธ์ค ๋ ๋ฒจ ์ฝ๋์ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ ์ฌ์ด์
- ์ํธ์์ฉ์ ์๊ฐํด ๋ด
์๋ค:
- void process_level(void)
- {
- msg = get_message();
- flag = true;
- }
- void interrupt_handler(void)
- {
- if (flag)
- process_message(msg);
- }
- ์ด ์ฝ๋์๋ ์ปดํ์ผ๋ฌ๊ฐ process_level() ์ ๋ค์๊ณผ ๊ฐ์ด ๋ณํํ๋ ๊ฒ์ ๋ง์
- ์๋จ์ด ์๊ณ , ์ด๋ฐ ๋ณํ์ ์ฑ๊ธ์ฐ๋ ๋์์๋ผ๋ฉด ์ค์ ๋ก ํ๋ฅญํ ์ ํ์ผ ์
- ์์ต๋๋ค:
- void process_level(void)
- {
- flag = true;
- msg = get_message();
- }
- ์ด ๋๊ฐ์ ๋ฌธ์ฅ ์ฌ์ด์ ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์ํ๋ค๋ฉด, interrupt_handler() ๋ ์๋ฏธ๋ฅผ
- ์ ์ ์๋ ๋ฉ์ธ์ง๋ฅผ ๋ฐ์ ์๋ ์์ต๋๋ค. ์ด๊ฑธ ๋ง๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด
- WRITE_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์:
- void process_level(void)
- {
- WRITE_ONCE(msg, get_message());
- WRITE_ONCE(flag, true);
- }
- void interrupt_handler(void)
- {
- if (READ_ONCE(flag))
- process_message(READ_ONCE(msg));
- }
- interrupt_handler() ์์์๋ ์ค์ฒฉ๋ ์ธํฐ๋ฝํธ๋ NMI ์ ๊ฐ์ด ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ
- ์ญ์ 'flag' ์ 'msg' ์ ์ ๊ทผํ๋ ๋๋ค๋ฅธ ๋ฌด์ธ๊ฐ์ ์ธํฐ๋ฝํธ ๋ ์ ์๋ค๋ฉด
- READ_ONCE() ์ WRITE_ONCE() ๋ฅผ ์ฌ์ฉํด์ผ ํจ์ ๊ธฐ์ตํด ๋์ธ์. ๋ง์ฝ ๊ทธ๋ฐ
- ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด, interrupt_handler() ์์์๋ ๋ฌธ์ํ ๋ชฉ์ ์ด ์๋๋ผ๋ฉด
- READ_ONCE() ์ WRITE_ONCE() ๋ ํ์์น ์์ต๋๋ค. (๊ทผ๋์ ๋ฆฌ๋
์ค ์ปค๋์์
- ์ค์ฒฉ๋ ์ธํฐ๋ฝํธ๋ ๋ณดํต ์ ์ผ์ด๋์ง ์์๋ ๊ธฐ์ตํด ๋์ธ์, ์ค์ ๋ก, ์ด๋ค
- ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ๊ฐ ์ธํฐ๋ฝํธ๊ฐ ํ์ฑํ๋ ์ฑ๋ก ๋ฆฌํดํ๋ฉด WARN_ONCE() ๊ฐ
- ์คํ๋ฉ๋๋ค.)
- ์ปดํ์ผ๋ฌ๋ READ_ONCE() ์ WRITE_ONCE() ๋ค์ READ_ONCE() ๋ WRITE_ONCE(),
- barrier(), ๋๋ ๋น์ทํ ๊ฒ๋ค์ ๋ด๊ณ ์์ง ์์ ์ฝ๋๋ฅผ ์์ง์ผ ์ ์์ ๊ฒ์ผ๋ก
- ๊ฐ์ ๋์ด์ผ ํฉ๋๋ค.
- ์ด ํจ๊ณผ๋ barrier() ๋ฅผ ํตํด์๋ ๋ง๋ค ์ ์์ง๋ง, READ_ONCE() ์
- WRITE_ONCE() ๊ฐ ์ข ๋ ์๋ชฉ ๋์ ์ ํ์
๋๋ค: READ_ONCE() ์ WRITE_ONCE()๋
- ์ปดํ์ผ๋ฌ์ ์ฃผ์ด์ง ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ํด์๋ง ์ต์ ํ ๊ฐ๋ฅ์ฑ์ ํฌ๊ธฐํ๋๋ก
- ํ์ง๋ง, barrier() ๋ ์ปดํ์ผ๋ฌ๊ฐ ์ง๊ธ๊น์ง ๊ธฐ๊ณ์ ๋ ์ง์คํฐ์ ์บ์ํด ๋์
- ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๊ฐ์ ๋ฒ๋ ค์ผ ํ๊ฒ ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฌผ๋ก , ์ปดํ์ผ๋ฌ๋
- READ_ONCE() ์ WRITE_ONCE() ๊ฐ ์ผ์ด๋ ์์๋ ์ง์ผ์ค๋๋ค, CPU ๋ ๋น์ฐํ
- ๊ทธ ์์๋ฅผ ์งํฌ ์๋ฌด๊ฐ ์์ง๋ง์.
- (*) ์ปดํ์ผ๋ฌ๋ ๋ค์์ ์์์์ ๊ฐ์ด ๋ณ์์์ ์คํ ์ด๋ฅผ ๋ ์กฐํด๋ผ ์๋ ์์ต๋๋ค:
- if (a)
- b = a;
- else
- b = 42;
- ์ปดํ์ผ๋ฌ๋ ์๋์ ๊ฐ์ ์ต์ ํ๋ก ๋ธ๋์น๋ฅผ ์ค์ผ ๊ฒ๋๋ค:
- b = 42;
- if (a)
- b = a;
- ์ฑ๊ธ ์ฐ๋ ๋ ์ฝ๋์์ ์ด ์ต์ ํ๋ ์์ ํ ๋ฟ ์๋๋ผ ๋ธ๋์น ๊ฐฏ์๋ฅผ
- ์ค์ฌ์ค๋๋ค. ํ์ง๋ง ์ํ๊น๊ฒ๋, ๋์์ฑ์ด ์๋ ์ฝ๋์์๋ ์ด ์ต์ ํ๋ ๋ค๋ฅธ
- CPU ๊ฐ 'b' ๋ฅผ ๋ก๋ํ ๋, -- 'a' ๊ฐ 0์ด ์๋๋ฐ๋ -- ๊ฐ์ง์ธ ๊ฐ, 42๋ฅผ ๋ณด๊ฒ
- ๋๋ ๊ฒฝ์ฐ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด๊ฑธ ๋ฐฉ์งํ๊ธฐ ์ํด WRITE_ONCE() ๋ฅผ
- ์ฌ์ฉํ์ธ์:
- if (a)
- WRITE_ONCE(b, a);
- else
- WRITE_ONCE(b, 42);
- ์ปดํ์ผ๋ฌ๋ ๋ก๋๋ฅผ ๋ง๋ค์ด๋ผ ์๋ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง
- ์์ง๋ง, ์บ์ ๋ผ์ธ ๋ฐ์ด์ฑ์ ์ผ์ผ์ผ ์ฑ๋ฅ๊ณผ ํ์ฅ์ฑ์ ๋จ์ด๋จ๋ฆด ์ ์์ต๋๋ค.
- ๋ ์กฐ๋ ๋ก๋๋ฅผ ๋ง๊ธฐ ์ํด์ READ_ONCE() ๋ฅผ ์ฌ์ฉํ์ธ์.
- (*) ์ ๋ ฌ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์์นํ, ํ๋ฒ์ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ ์ธ์คํธ๋ญ์
์ผ๋ก ์ก์ธ์ค
- ๊ฐ๋ฅํ ํฌ๊ธฐ์ ๋ฐ์ดํฐ๋ ํ๋์ ํฐ ์ก์ธ์ค๊ฐ ์ฌ๋ฌ๊ฐ์ ์์ ์ก์ธ์ค๋ค๋ก
- ๋์ฒด๋๋ "๋ก๋ ํฐ์ด๋ง(load tearing)" ๊ณผ "์คํ ์ด ํฐ์ด๋ง(store tearing)" ์
- ๋ฐฉ์งํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฃผ์ด์ง ์ํคํ
์ณ๊ฐ 7-bit imeediate field ๋ฅผ ๊ฐ๋
- 16-bit ์คํ ์ด ์ธ์คํธ๋ญ์
์ ์ ๊ณตํ๋ค๋ฉด, ์ปดํ์ผ๋ฌ๋ ๋ค์์ 32-bit ์คํ ์ด๋ฅผ
- ๊ตฌํํ๋๋ฐ์ ๋๊ฐ์ 16-bit store-immediate ๋ช
๋ น์ ์ฌ์ฉํ๋ ค ํ ๊ฒ๋๋ค:
- p = 0x00010002;
- ์คํ ์ด ํ ์์๋ฅผ ๋ง๋ค๊ณ ๊ทธ ๊ฐ์ ์คํ ์ด ํ๊ธฐ ์ํด ๋๊ฐ๊ฐ ๋๋ ์ธ์คํธ๋ญ์
์
- ์ฌ์ฉํ๊ฒ ๋๋, ์ด๋ฐ ์ข
๋ฅ์ ์ต์ ํ๋ฅผ GCC ๋ ์ค์ ๋ก ํจ์ ๋ถ๋ ์์ ๋์ญ์์ค.
- ์ด ์ต์ ํ๋ ์ฑ๊ธ ์ฐ๋ ๋ ์ฝ๋์์๋ ์ฑ๊ณต์ ์ธ ์ต์ ํ ์
๋๋ค. ์ค์ ๋ก, ๊ทผ๋์
- ๋ฐ์ํ (๊ทธ๋ฆฌ๊ณ ๊ณ ์ณ์ง) ๋ฒ๊ทธ๋ GCC ๊ฐ volatile ์คํ ์ด์ ๋น์ ์์ ์ผ๋ก ์ด
- ์ต์ ํ๋ฅผ ์ฌ์ฉํ๊ฒ ํ์ต๋๋ค. ๊ทธ๋ฐ ๋ฒ๊ทธ๊ฐ ์๋ค๋ฉด, ๋ค์์ ์์์
- WRITE_ONCE() ์ ์ฌ์ฉ์ ์คํ ์ด ํฐ์ด๋ง์ ๋ฐฉ์งํฉ๋๋ค:
- WRITE_ONCE(p, 0x00010002);
- Packed ๊ตฌ์กฐ์ฒด์ ์ฌ์ฉ ์ญ์ ๋ค์์ ์์ฒ๋ผ ๋ก๋ / ์คํ ์ด ํฐ์ด๋ง์ ์ ๋ฐํ ์
- ์์ต๋๋ค:
- struct __attribute__((__packed__)) foo {
- short a;
- int b;
- short c;
- };
- struct foo foo1, foo2;
- ...
- foo2.a = foo1.a;
- foo2.b = foo1.b;
- foo2.c = foo1.c;
- READ_ONCE() ๋ WRITE_ONCE() ๋ ์๊ณ volatile ๋งํน๋ ์๊ธฐ ๋๋ฌธ์,
- ์ปดํ์ผ๋ฌ๋ ์ด ์ธ๊ฐ์ ๋์
๋ฌธ์ ๋๊ฐ์ 32-bit ๋ก๋์ ๋๊ฐ์ 32-bit ์คํ ์ด๋ก
- ๋ณํํ ์ ์์ต๋๋ค. ์ด๋ 'foo1.b' ์ ๊ฐ์ ๋ก๋ ํฐ์ด๋ง๊ณผ 'foo2.b' ์
- ์คํ ์ด ํฐ์ด๋ง์ ์ด๋ํ ๊ฒ๋๋ค. ์ด ์์์๋ READ_ONCE() ์ WRITE_ONCE()
- ๊ฐ ํฐ์ด๋ง์ ๋ง์ ์ ์์ต๋๋ค:
- foo2.a = foo1.a;
- WRITE_ONCE(foo2.b, READ_ONCE(foo1.b));
- foo2.c = foo1.c;
- ๊ทธ๋ ์ง๋ง, volatile ๋ก ๋งํฌ๋ ๋ณ์์ ๋ํด์๋ READ_ONCE() ์ WRITE_ONCE() ๊ฐ
- ํ์์น ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, 'jiffies' ๋ volatile ๋ก ๋งํฌ๋์ด ์๊ธฐ ๋๋ฌธ์,
- READ_ONCE(jiffies) ๋ผ๊ณ ํ ํ์๊ฐ ์์ต๋๋ค. READ_ONCE() ์ WRITE_ONCE() ๊ฐ
- ์ค์ volatile ์บ์คํ
์ผ๋ก ๊ตฌํ๋์ด ์์ด์ ์ธ์๊ฐ ์ด๋ฏธ volatile ๋ก ๋งํฌ๋์ด
- ์๋ค๋ฉด ๋๋ค๋ฅธ ํจ๊ณผ๋ฅผ ๋ด์ง๋ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
- ์ด ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด๋ค์ CPU ์๋ ์ง์ ์ ํจ๊ณผ๋ฅผ ์ ํ ๋ง๋ค์ง ์๊ธฐ ๋๋ฌธ์, ๊ฒฐ๊ตญ์
- ์ฌ๋ฐฐ์น๊ฐ ์ผ์ด๋ ์๋ ์์์ ๋ถ๋ ๊ธฐ์ตํด ๋์ญ์์ค.
- CPU ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด
- -----------------
- ๋ฆฌ๋
์ค ์ปค๋์ ๋ค์์ ์ฌ๋๊ฐ ๊ธฐ๋ณธ CPU ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค:
- TYPE MANDATORY SMP CONDITIONAL
- =============== ======================= ===========================
- ๋ฒ์ฉ mb() smp_mb()
- ์ฐ๊ธฐ wmb() smp_wmb()
- ์ฝ๊ธฐ rmb() smp_rmb()
- ๋ฐ์ดํฐ ์์กด์ฑ read_barrier_depends() smp_read_barrier_depends()
- ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ
- ํฌํจํฉ๋๋ค. ๋ฐ์ดํฐ ์์กด์ฑ์ ์ปดํ์ผ๋ฌ์์ ์ถ๊ฐ์ ์ธ ์์ ๋ณด์ฅ์ ํฌํจํ์ง
- ์์ต๋๋ค.
- ๋ฐฉ๋ฐฑ: ๋ฐ์ดํฐ ์์กด์ฑ์ด ์๋ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ ํด๋น ๋ก๋๋ฅผ ์ฌ๋ฐ๋ฅธ ์์๋ก ์ผ์ผํฌ
- ๊ฒ์ผ๋ก (์: `a[b]` ๋ a[b] ๋ฅผ ๋ก๋ ํ๊ธฐ ์ ์ b ์ ๊ฐ์ ๋จผ์ ๋ก๋ํ๋ค)
- ๊ธฐ๋๋์ง๋ง, C ์ธ์ด ์ฌ์์๋ ์ปดํ์ผ๋ฌ๊ฐ b ์ ๊ฐ์ ์ถ์ธก (์: 1 ๊ณผ ๊ฐ์) ํด์
- b ๋ก๋ ์ ์ a ๋ก๋๋ฅผ ํ๋ ์ฝ๋ (์: tmp = a[1]; if (b != 1) tmp = a[b]; ) ๋ฅผ
- ๋ง๋ค์ง ์์์ผ ํ๋ค๋ ๋ด์ฉ ๊ฐ์ ๊ฑด ์์ต๋๋ค. ๋ํ ์ปดํ์ผ๋ฌ๋ a[b] ๋ฅผ ๋ก๋ํ
- ํ์ b ๋ฅผ ๋๋ค์ ๋ก๋ํ ์๋ ์์ด์, a[b] ๋ณด๋ค ์ต์ ๋ฒ์ ์ b ๊ฐ์ ๊ฐ์ง ์๋
- ์์ต๋๋ค. ์ด๋ฐ ๋ฌธ์ ๋ค์ ํด๊ฒฐ์ฑ
์ ๋ํ ์๊ฒฌ ์ผ์น๋ ์์ง ์์ต๋๋ค๋ง, ์ผ๋จ
- READ_ONCE() ๋งคํฌ๋ก๋ถํฐ ๋ณด๊ธฐ ์์ํ๋๊ฒ ์ข์ ์์์ด ๋ ๊ฒ๋๋ค.
- SMP ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ ์ ๋ํ๋ก์ธ์๋ก ์ปดํ์ผ๋ ์์คํ
์์๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด๋ก
- ๋ฐ๋๋๋ฐ, ํ๋์ CPU ๋ ์ค์ค๋ก ์ผ๊ด์ฑ์ ์ ์งํ๊ณ , ๊ฒน์น๋ ์ก์ธ์ค๋ค ์ญ์ ์ฌ๋ฐ๋ฅธ
- ์์๋ก ํํด์ง ๊ฒ์ผ๋ก ์๊ฐ๋๊ธฐ ๋๋ฌธ์
๋๋ค. ํ์ง๋ง, ์๋์ "Virtual Machine
- Guests" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ญ์์ค.
- [!] SMP ์์คํ
์์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ก์ ์ ๊ทผ๋ค์ ์์ ์ธ์์ผ ํ ๋, SMP ๋ฉ๋ชจ๋ฆฌ
- ๋ฐฐ๋ฆฌ์ด๋ _๋ฐ๋์_ ์ฌ์ฉ๋์ด์ผ ํจ์ ๊ธฐ์ตํ์ธ์, ๊ทธ๋์ ๋ฝ์ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก๋
- ์ถฉ๋ถํ๊ธด ํ์ง๋ง ๋ง์ด์ฃ .
- Mandatory ๋ฐฐ๋ฆฌ์ด๋ค์ SMP ์์คํ
์์๋ UP ์์คํ
์์๋ SMP ํจ๊ณผ๋ง ํต์ ํ๊ธฐ์๋
- ๋ถํ์ํ ์ค๋ฒํค๋๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ SMP ํจ๊ณผ๋ง ํต์ ํ๋ฉด ๋๋ ๊ณณ์๋ ์ฌ์ฉ๋์ง ์์์ผ
- ํฉ๋๋ค. ํ์ง๋ง, ๋์จํ ์์ ๊ท์น์ ๋ฉ๋ชจ๋ฆฌ I/O ์๋์ฐ๋ฅผ ํตํ MMIO ์ ํจ๊ณผ๋ฅผ
- ํต์ ํ ๋์๋ mandatory ๋ฐฐ๋ฆฌ์ด๋ค์ด ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์ด ๋ฐฐ๋ฆฌ์ด๋ค์
- ์ปดํ์ผ๋ฌ์ CPU ๋ชจ๋ ์ฌ๋ฐฐ์น๋ฅผ ๋ชปํ๋๋ก ํจ์ผ๋ก์จ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ด ๋๋ฐ์ด์ค์
- ๋ณด์ฌ์ง๋ ์์์๋ ์ํฅ์ ์ฃผ๊ธฐ ๋๋ฌธ์, SMP ๊ฐ ์๋ ์์คํ
์ด๋ผ ํ ์ง๋ผ๋ ํ์ํ ์
- ์์ต๋๋ค.
- ์ผ๋ถ ๊ณ ๊ธ ๋ฐฐ๋ฆฌ์ด ํจ์๋ค๋ ์์ต๋๋ค:
- (*) smp_store_mb(var, value)
- ์ด ํจ์๋ ํน์ ๋ณ์์ ํน์ ๊ฐ์ ๋์
ํ๊ณ ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์นฉ๋๋ค.
- UP ์ปดํ์ผ์์๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด๋ณด๋ค ๋ํ ๊ฒ์ ์น๋ค๊ณ ๋ ๋ณด์ฅ๋์ง ์์ต๋๋ค.
- (*) smp_mb__before_atomic();
- (*) smp_mb__after_atomic();
- ์ด๊ฒ๋ค์ ๊ฐ์ ๋ฆฌํดํ์ง ์๋ (๋ํ๊ธฐ, ๋นผ๊ธฐ, ์ฆ๊ฐ, ๊ฐ์์ ๊ฐ์) ์ดํ ๋ฏน
- ํจ์๋ค์ ์ํ, ํนํ ๊ทธ๊ฒ๋ค์ด ๋ ํผ๋ฐ์ค ์นด์ดํ
์ ์ฌ์ฉ๋ ๋๋ฅผ ์ํ
- ํจ์๋ค์
๋๋ค. ์ด ํจ์๋ค์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ๊ณ ์์ง๋ ์์ต๋๋ค.
- ์ด๊ฒ๋ค์ ๊ฐ์ ๋ฆฌํดํ์ง ์์ผ๋ฉฐ ์ดํ ๋ฏนํ (set_bit ๊ณผ clear_bit ๊ฐ์) ๋นํธ
- ์ฐ์ฐ์๋ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ํ ์๋ก, ๊ฐ์ฒด ํ๋๋ฅผ ๋ฌดํจํ ๊ฒ์ผ๋ก ํ์ํ๊ณ ๊ทธ ๊ฐ์ฒด์ ๋ ํผ๋ฐ์ค ์นด์ดํธ๋ฅผ
- ๊ฐ์์ํค๋ ๋ค์ ์ฝ๋๋ฅผ ๋ณด์ธ์:
- obj->dead = 1;
- smp_mb__before_atomic();
- atomic_dec(&obj->ref_count);
- ์ด ์ฝ๋๋ ๊ฐ์ฒด์ ์
๋ฐ์ดํธ๋ death ๋งํฌ๊ฐ ๋ ํผ๋ฐ์ค ์นด์ดํฐ ๊ฐ์ ๋์
- *์ ์* ๋ณด์ผ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
- ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ Documentation/atomic_ops.txt ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
- ์ด๋์ ์ด๊ฒ๋ค์ ์ฌ์ฉํด์ผ ํ ์ง ๊ถ๊ธํ๋ค๋ฉด "์ดํ ๋ฏน ์คํผ๋ ์ด์
" ์๋ธ์น์
์
- ์ฐธ๊ณ ํ์ธ์.
- (*) lockless_dereference();
- ์ด ํจ์๋ smp_read_barrier_depends() ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ๋
- ํฌ์ธํฐ ์ฝ์ด์ค๊ธฐ ๋ํผ(wrapper) ํจ์๋ก ์๊ฐ๋ ์ ์์ต๋๋ค.
- ๊ฐ์ฒด์ ๋ผ์ดํํ์์ด RCU ์ธ์ ๋ฉ์ปค๋์ฆ์ผ๋ก ๊ด๋ฆฌ๋๋ค๋ ์ ์ ์ ์ธํ๋ฉด
- rcu_dereference() ์๋ ์ ์ฌํ๋ฐ, ์๋ฅผ ๋ค๋ฉด ๊ฐ์ฒด๊ฐ ์์คํ
์ด ๊บผ์ง ๋์๋ง
- ์ ๊ฑฐ๋๋ ๊ฒฝ์ฐ ๋ฑ์
๋๋ค. ๋ํ, lockless_dereference() ์ RCU ์ ํจ๊ป
- ์ฌ์ฉ๋ ์๋, RCU ์์ด ์ฌ์ฉ๋ ์๋ ์๋ ์ผ๋ถ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ฌ์ฉ๋๊ณ
- ์์ต๋๋ค.
- (*) dma_wmb();
- (*) dma_rmb();
- ์ด๊ฒ๋ค์ CPU ์ DMA ๊ฐ๋ฅํ ๋๋ฐ์ด์ค์์ ๋ชจ๋ ์ก์ธ์ค ๊ฐ๋ฅํ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์
- ์ฝ๊ธฐ, ์ฐ๊ธฐ ์์
๋ค์ ์์๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด consistent memory ์์ ์ฌ์ฉํ๊ธฐ
- ์ํ ๊ฒ๋ค์
๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋๋ฐ์ด์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ฉฐ, ๋์คํฌ๋ฆฝํฐ ์ํ ๊ฐ์ ์ฌ์ฉํด
- ๋์คํฌ๋ฆฝํฐ๊ฐ ๋๋ฐ์ด์ค์ ์ํด ์๋์ง ์๋๋ฉด CPU ์ ์ํด ์๋์ง ํ์ํ๊ณ ,
- ๊ณต์ง์ฉ ์ด์ธ์ข
(doorbell) ์ ์ฌ์ฉํด ์
๋ฐ์ดํธ๋ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋๋ฐ์ด์ค์ ์ฌ์ฉ
- ๊ฐ๋ฅํด์ก์์ ๊ณต์งํ๋ ๋๋ฐ์ด์ค ๋๋ผ์ด๋ฒ๋ฅผ ์๊ฐํด ๋ด
์๋ค:
- if (desc->status != DEVICE_OWN) {
- /* ๋์คํฌ๋ฆฝํฐ๋ฅผ ์์ ํ๊ธฐ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ง ์์ */
- dma_rmb();
- /* ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ */
- read_data = desc->data;
- desc->data = write_data;
- /* ์ํ ์
๋ฐ์ดํธ ์ ์์ ์ฌํญ์ ๋ฐ์ */
- dma_wmb();
- /* ์์ ๊ถ์ ์์ */
- desc->status = DEVICE_OWN;
- /* MMIO ๋ฅผ ํตํด ๋๋ฐ์ด์ค์ ๊ณต์ง๋ฅผ ํ๊ธฐ ์ ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋๊ธฐํ */
- wmb();
- /* ์
๋ฐ์ดํธ๋ ๋์คํฌ๋ฆฝํฐ์ ๋๋ฐ์ด์ค์ ๊ณต์ง */
- writel(DESC_NOTIFY, doorbell);
- }
- dma_rmb() ๋ ๋์คํฌ๋ฆฝํฐ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ค๊ธฐ ์ ์ ๋๋ฐ์ด์ค๊ฐ ์์ ๊ถ์
- ๋ด๋์์์ ๋ณด์ฅํ๊ฒ ํ๊ณ , dma_wmb() ๋ ๋๋ฐ์ด์ค๊ฐ ์์ ์ด ์์ ๊ถ์ ๋ค์
- ๊ฐ์ก์์ ๋ณด๊ธฐ ์ ์ ๋์คํฌ๋ฆฝํฐ์ ๋ฐ์ดํฐ๊ฐ ์ฐ์์์ ๋ณด์ฅํฉ๋๋ค. wmb() ๋
- ์บ์ ์ผ๊ด์ฑ์ด ์๋ (cache incoherent) MMIO ์์ญ์ ์ฐ๊ธฐ๋ฅผ ์๋ํ๊ธฐ ์ ์
- ์บ์ ์ผ๊ด์ฑ์ด ์๋ ๋ฉ๋ชจ๋ฆฌ (cache coherent memory) ์ฐ๊ธฐ๊ฐ ์๋ฃ๋์์์
- ๋ณด์ฅํด์ฃผ๊ธฐ ์ํด ํ์ํฉ๋๋ค.
- consistent memory ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ํด์ Documentation/DMA-API.txt
- ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
- MMIO ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด
- ----------------
- ๋ฆฌ๋
์ค ์ปค๋์ ๋ํ memory-mapped I/O ์ฐ๊ธฐ๋ฅผ ์ํ ํน๋ณํ ๋ฐฐ๋ฆฌ์ด๋ ๊ฐ์ง๊ณ
- ์์ต๋๋ค:
- mmiowb();
- ์ด๊ฒ์ mandatory ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด์ ๋ณ์ข
์ผ๋ก, ์ํ๋ ์์ ๊ท์น์ I/O ์์ญ์์ผ๋ก์
- ์ฐ๊ธฐ๊ฐ ๋ถ๋ถ์ ์ผ๋ก ์์๋ฅผ ๋ง์ถ๋๋ก ํด์ค๋๋ค. ์ด ํจ์๋ CPU->ํ๋์จ์ด ์ฌ์ด๋ฅผ
- ๋์ด์ ์ค์ ํ๋์จ์ด์๊น์ง ์ผ๋ถ ์์ค์ ์ํฅ์ ๋ผ์นฉ๋๋ค.
- ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ "Acquire vs I/O ์ก์ธ์ค" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- =========================
- ์๋ฌต์ ์ปค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด
- =========================
- ๋ฆฌ๋
์ค ์ปค๋์ ์ผ๋ถ ํจ์๋ค์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ด์ฅํ๊ณ ์๋๋ฐ, ๋ฝ(lock)๊ณผ
- ์ค์ผ์ฅด๋ง ๊ด๋ จ ํจ์๋ค์ด ๋๋ถ๋ถ์
๋๋ค.
- ์ฌ๊ธฐ์ _์ต์ํ์_ ๋ณด์ฅ์ ์ค๋ช
ํฉ๋๋ค; ํน์ ์ํคํ
์ณ์์๋ ์ด ์ค๋ช
๋ณด๋ค ๋ ๋ง์
- ๋ณด์ฅ์ ์ ๊ณตํ ์๋ ์์ต๋๋ค๋ง ํด๋น ์ํคํ
์ณ์ ์ข
์์ ์ธ ์ฝ๋ ์ธ์ ๋ถ๋ถ์์๋
- ๊ทธ๋ฐ ๋ณด์ฅ์ ๊ธฐ๋ํด์ ์๋ ๊ฒ๋๋ค.
- ๋ฝ ACQUISITION ํจ์
- -------------------
- ๋ฆฌ๋
์ค ์ปค๋์ ๋ค์ํ ๋ฝ ๊ตฌ์ฑ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค:
- (*) ์คํ ๋ฝ
- (*) R/W ์คํ ๋ฝ
- (*) ๋ฎคํ
์ค
- (*) ์ธ๋งํฌ์ด
- (*) R/W ์ธ๋งํฌ์ด
- ๊ฐ ๊ตฌ์ฑ์ฒด๋ง๋ค ๋ชจ๋ ๊ฒฝ์ฐ์ "ACQUIRE" ์คํผ๋ ์ด์
๊ณผ "RELEASE" ์คํผ๋ ์ด์
์ ๋ณ์ข
์ด
- ์กด์ฌํฉ๋๋ค. ์ด ์คํผ๋ ์ด์
๋ค์ ๋ชจ๋ ์ ์ ํ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ๊ณ ์์ต๋๋ค:
- (1) ACQUIRE ์คํผ๋ ์ด์
์ ์ํฅ:
- ACQUIRE ๋ค์์ ์์ฒญ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ ACQUIRE ์คํผ๋ ์ด์
์ด ์๋ฃ๋
- ๋ค์ ์๋ฃ๋ฉ๋๋ค.
- ACQUIRE ์์์ ์์ฒญ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ ACQUIRE ์คํผ๋ ์ด์
์ด ์๋ฃ๋ ํ์
- ์๋ฃ๋ ์ ์์ต๋๋ค. smp_mb__before_spinlock() ๋ค์ ACQUIRE ๊ฐ ์คํ๋๋
- ์ฝ๋ ๋ธ๋ก์ ๋ธ๋ก ์์ ์คํ ์ด๋ฅผ ๋ธ๋ก ๋ค์ ๋ก๋์ ์คํ ์ด์ ๋ํด ์์
- ๋ง์ถฅ๋๋ค. ์ด๊ฑด smp_mb() ๋ณด๋ค ์ํ๋ ๊ฒ์์ ๊ธฐ์ตํ์ธ์! ๋ง์ ์ํคํ
์ณ์์
- smp_mb__before_spinlock() ์ ์ฌ์ค ์๋ฌด์ผ๋ ํ์ง ์์ต๋๋ค.
- (2) RELEASE ์คํผ๋ ์ด์
์ ์ํฅ:
- RELEASE ์์์ ์์ฒญ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ RELEASE ์คํผ๋ ์ด์
์ด ์๋ฃ๋๊ธฐ
- ์ ์ ์๋ฃ๋ฉ๋๋ค.
- RELEASE ๋ค์์ ์์ฒญ๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ RELEASE ์คํผ๋ ์ด์
์๋ฃ ์ ์
- ์๋ฃ๋ ์ ์์ต๋๋ค.
- (3) ACQUIRE vs ACQUIRE ์ํฅ:
- ์ด๋ค ACQUIRE ์คํผ๋ ์ด์
๋ณด๋ค ์์์ ์์ฒญ๋ ๋ชจ๋ ACQUIRE ์คํผ๋ ์ด์
์ ๊ทธ
- ACQUIRE ์คํผ๋ ์ด์
์ ์ ์๋ฃ๋ฉ๋๋ค.
- (4) ACQUIRE vs RELEASE implication:
- ์ด๋ค RELEASE ์คํผ๋ ์ด์
๋ณด๋ค ์์ ์์ฒญ๋ ACQUIRE ์คํผ๋ ์ด์
์ ๊ทธ RELEASE
- ์คํผ๋ ์ด์
๋ณด๋ค ๋จผ์ ์๋ฃ๋ฉ๋๋ค.
- (5) ์คํจํ ์กฐ๊ฑด์ ACQUIRE ์ํฅ:
- ACQUIRE ์คํผ๋ ์ด์
์ ์ผ๋ถ ๋ฝ(lock) ๋ณ์ข
์ ๋ฝ์ด ๊ณง๋ฐ๋ก ํ๋ํ๊ธฐ์๋
- ๋ถ๊ฐ๋ฅํ ์ํ์ด๊ฑฐ๋ ๋ฝ์ด ํ๋ ๊ฐ๋ฅํด์ง๋๋ก ๊ธฐ๋ค๋ฆฌ๋ ๋์ค ์๊ทธ๋์ ๋ฐ๊ฑฐ๋
- ํด์ ์คํจํ ์ ์์ต๋๋ค. ์คํจํ ๋ฝ์ ์ด๋ค ๋ฐฐ๋ฆฌ์ด๋ ๋ดํฌํ์ง ์์ต๋๋ค.
- [!] ์ฐธ๊ณ : ๋ฝ ACQUIRE ์ RELEASE ๊ฐ ๋จ๋ฐฉํฅ ๋ฐฐ๋ฆฌ์ด์ฌ์ ๋ํ๋๋ ํ์ ์ค ํ๋๋
- ํฌ๋ฆฌํฐ์ปฌ ์น์
๋ฐ๊นฅ์ ์ธ์คํธ๋ญ์
์ ์ํฅ์ด ํฌ๋ฆฌํฐ์ปฌ ์น์
๋ด๋ถ๋ก๋ ๋ค์ด์ฌ ์
- ์๋ค๋ ๊ฒ์
๋๋ค.
- RELEASE ํ์ ์์ฒญ๋๋ ACQUIRE ๋ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ผ ์ฌ๊ฒจ์ง๋ฉด ์๋๋๋ฐ,
- ACQUIRE ์์ ์ก์ธ์ค๊ฐ ACQUIRE ํ์ ์ํ๋ ์ ์๊ณ , RELEASE ํ์ ์ก์ธ์ค๊ฐ
- RELEASE ์ ์ ์ํ๋ ์๋ ์์ผ๋ฉฐ, ๊ทธ ๋๊ฐ์ ์ก์ธ์ค๊ฐ ์๋ก๋ฅผ ์ง๋์น ์๋ ์๊ธฐ
- ๋๋ฌธ์
๋๋ค:
- *A = a;
- ACQUIRE M
- RELEASE M
- *B = b;
- ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ ์๋ ์์ต๋๋ค:
- ACQUIRE M, STORE *B, STORE *A, RELEASE M
- ACQUIRE ์ RELEASE ๊ฐ ๋ฝ ํ๋๊ณผ ํด์ ๋ผ๋ฉด, ๊ทธ๋ฆฌ๊ณ ๋ฝ์ ACQUIRE ์ RELEASE ๊ฐ
- ๊ฐ์ ๋ฝ ๋ณ์์ ๋ํ ๊ฒ์ด๋ผ๋ฉด, ํด๋น ๋ฝ์ ์ฅ๊ณ ์์ง ์์ ๋ค๋ฅธ CPU ์ ์์ผ์๋
- ์ด์ ๊ฐ์ ์ฌ๋ฐฐ์น๊ฐ ์ผ์ด๋๋ ๊ฒ์ผ๋ก ๋ณด์ผ ์ ์์ต๋๋ค. ์์ฝํ์๋ฉด, ACQUIRE ์
- ์ด์ด RELEASE ์คํผ๋ ์ด์
์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ ํ์๊ฐ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ก
- ์๊ฐ๋์ด์ -์๋ฉ๋๋ค-.
- ๋น์ทํ๊ฒ, ์์ ๋ฐ๋ ์ผ์ด์ค์ธ RELEASE ์ ACQUIRE ๋๊ฐ ์คํผ๋ ์ด์
์ ์์ฐจ์ ์คํ
- ์ญ์ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์, RELEASE, ACQUIRE ๋ก
- ๊ท์ ๋๋ ํฌ๋ฆฌํฐ์ปฌ ์น์
์ CPU ์ํ์ RELEASE ์ ACQUIRE ๋ฅผ ๊ฐ๋ก์ง๋ฅผ ์ ์์ผ๋ฏ๋ก,
- ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋:
- *A = a;
- RELEASE M
- ACQUIRE N
- *B = b;
- ๋ค์๊ณผ ๊ฐ์ด ์ํ๋ ์ ์์ต๋๋ค:
- ACQUIRE N, STORE *B, STORE *A, RELEASE M
- ์ด๋ฐ ์ฌ๋ฐฐ์น๋ ๋ฐ๋๋ฝ์ ์ผ์ผํฌ ์๋ ์์ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค. ํ์ง๋ง, ๊ทธ๋ฐ
- ๋ฐ๋๋ฝ์ ์กฐ์ง์ด ์๋ค๋ฉด RELEASE ๋ ๋จ์ํ ์๋ฃ๋ ๊ฒ์ด๋ฏ๋ก ๋ฐ๋๋ฝ์ ์กด์ฌํ ์
- ์์ต๋๋ค.
- ์ด๊ฒ ์ด๋ป๊ฒ ์ฌ๋ฐ๋ฅธ ๋์์ ํ ์ ์์๊น์?
- ์ฐ๋ฆฌ๊ฐ ์ด์ผ๊ธฐ ํ๊ณ ์๋๊ฑด ์ฌ๋ฐฐ์น๋ฅผ ํ๋ CPU ์ ๋ํ ์ด์ผ๊ธฐ์ด์ง,
- ์ปดํ์ผ๋ฌ์ ๋ํ ๊ฒ์ด ์๋๋ ์ ์ด ํต์ฌ์
๋๋ค. ์ปดํ์ผ๋ฌ (๋๋, ๊ฐ๋ฐ์)
- ๊ฐ ์คํผ๋ ์ด์
๋ค์ ์ด๋ ๊ฒ ์ฌ๋ฐฐ์นํ๋ฉด, ๋ฐ๋๋ฝ์ด ์ผ์ด๋ ์ -์์ต-๋๋ค.
- ํ์ง๋ง CPU ๊ฐ ์คํผ๋ ์ด์
๋ค์ ์ฌ๋ฐฐ์น ํ๋ค๋๊ฑธ ์๊ฐํด ๋ณด์ธ์. ์ด ์์์,
- ์ด์
๋ธ๋ฆฌ ์ฝ๋ ์์ผ๋ก๋ ์ธ๋ฝ์ด ๋ฝ์ ์์๊ฒ ๋์ด ์์ต๋๋ค. CPU ๊ฐ ์ด๋ฅผ
- ์ฌ๋ฐฐ์นํด์ ๋ค์ ๋ฝ ์คํผ๋ ์ด์
์ ๋จผ์ ์คํํ๊ฒ ๋ฉ๋๋ค. ๋ง์ฝ ๋ฐ๋๋ฝ์ด
- ์กด์ฌํ๋ค๋ฉด, ์ด ๋ฝ ์คํผ๋ ์ด์
์ ๊ทธ์ ์คํ์ ํ๋ฉฐ ๊ณ์ํด์ ๋ฝ์
- ์๋ํฉ๋๋ค (๋๋, ํ์ฐธ ํ์๊ฒ ์ง๋ง, ์ ๋ญ๋๋ค). CPU ๋ ์ธ์ ๊ฐ๋
- (์ด์
๋ธ๋ฆฌ ์ฝ๋์์๋ ๋ฝ์ ์์๋) ์ธ๋ฝ ์คํผ๋ ์ด์
์ ์คํํ๋๋ฐ, ์ด ์ธ๋ฝ
- ์คํผ๋ ์ด์
์ด ์ ์ฌ์ ๋ฐ๋๋ฝ์ ํด๊ฒฐํ๊ณ , ๋ฝ ์คํผ๋ ์ด์
๋ ๋ค์ด์ด ์ฑ๊ณตํ๊ฒ
- ๋ฉ๋๋ค.
- ํ์ง๋ง ๋ง์ฝ ๋ฝ์ด ์ ์ ์๋ ํ์
์ด์๋ค๋ฉด์? ๊ทธ๋ฐ ๊ฒฝ์ฐ์ ์ฝ๋๋
- ์ค์ผ์ฅด๋ฌ๋ก ๋ค์ด๊ฐ๋ ค ํ ๊ฑฐ๊ณ , ์ฌ๊ธฐ์ ๊ฒฐ๊ตญ์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ง๋๊ฒ
- ๋๋๋ฐ, ์ด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์์ ์ธ๋ฝ ์คํผ๋ ์ด์
์ด ์๋ฃ๋๋๋ก ๋ง๋ค๊ณ ,
- ๋ฐ๋๋ฝ์ ์ด๋ฒ์๋ ํด๊ฒฐ๋ฉ๋๋ค. ์ ์ ์๋ ํ์์ ์ธ๋ฝ ์ฌ์ด์ ๊ฒฝ์ฃผ ์ํฉ
- (race) ๋ ์์ ์ ์๊ฒ ์ต๋๋ค๋ง, ๋ฝ ๊ด๋ จ ๊ธฐ๋ฅ๋ค์ ๊ทธ๋ฐ ๊ฒฝ์ฃผ ์ํฉ์ ๋ชจ๋
- ๊ฒฝ์ฐ์ ์ ๋๋ก ํด๊ฒฐํ ์ ์์ด์ผ ํฉ๋๋ค.
- ๋ฝ๊ณผ ์ธ๋งํฌ์ด๋ UP ์ปดํ์ผ๋ ์์คํ
์์์ ์์์ ๋ํด ๋ณด์ฅ์ ํ์ง ์๊ธฐ ๋๋ฌธ์,
- ๊ทธ๋ฐ ์ํฉ์์ ์ธํฐ๋ฝํธ ๋นํ์ฑํ ์คํผ๋ ์ด์
๊ณผ ํจ๊ป๊ฐ ์๋๋ผ๋ฉด ์ด๋ค ์ผ์๋ - ํนํ
- I/O ์ก์ธ์ค์ ๊ด๋ จํด์๋ - ์ ๋๋ก ์ฌ์ฉ๋ ์ ์์ ๊ฒ๋๋ค.
- "CPU ๊ฐ ACQUIRING ๋ฐฐ๋ฆฌ์ด ํจ๊ณผ" ์น์
๋ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์๊ฐํด ๋ด
์๋ค:
- *A = a;
- *B = b;
- ACQUIRE
- *C = c;
- *D = d;
- RELEASE
- *E = e;
- *F = f;
- ์ฌ๊ธฐ์ ๋ค์์ ์ด๋ฒคํธ ์ํ์ค๊ฐ ์๊ธธ ์ ์์ต๋๋ค:
- ACQUIRE, {*F,*A}, *E, {*C,*D}, *B, RELEASE
- [+] {*F,*A} ๋ ์กฐํฉ๋ ์ก์ธ์ค๋ฅผ ์๋ฏธํฉ๋๋ค.
- ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ๊ฑด ๋ถ๊ฐ๋ฅํ์ฃ :
- {*F,*A}, *B, ACQUIRE, *C, *D, RELEASE, *E
- *A, *B, *C, ACQUIRE, *D, RELEASE, *E, *F
- *A, *B, ACQUIRE, *C, RELEASE, *D, *E, *F
- *B, ACQUIRE, *C, *D, RELEASE, {*F,*A}, *E
- ์ธํฐ๋ฝํธ ๋นํ์ฑํ ํจ์
- ----------------------
- ์ธํฐ๋ฝํธ๋ฅผ ๋นํ์ฑํ ํ๋ ํจ์ (ACQUIRE ์ ๋์ผ) ์ ์ธํฐ๋ฝํธ๋ฅผ ํ์ฑํ ํ๋ ํจ์
- (RELEASE ์ ๋์ผ) ๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด์ฒ๋ผ๋ง ๋์ํฉ๋๋ค. ๋ฐ๋ผ์, ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ
- ๋ฐฐ๋ฆฌ์ด๋ I/O ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ์ํฉ์ด๋ผ๋ฉด ๊ทธ ๋ฐฐ๋ฆฌ์ด๋ค์ ์ธํฐ๋ฝํธ ๋นํ์ฑํ ํจ์
- ์ธ์ ๋ฐฉ๋ฒ์ผ๋ก ์ ๊ณต๋์ด์ผ๋ง ํฉ๋๋ค.
- ์ฌ๋ฆฝ๊ณผ ์จ์ดํฌ์
ํจ์
- --------------------
- ๊ธ๋ก๋ฒ ๋ฐ์ดํฐ์ ํ์๋ ์ด๋ฒคํธ์ ์ํด ํ๋ก์ธ์ค๋ฅผ ์ ์ ๋น ํธ๋ฆฌ๋ ๊ฒ๊ณผ ๊นจ์ฐ๋ ๊ฒ์
- ํด๋น ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ํ์คํฌ์ ํ์คํฌ ์ํ์ ๊ทธ ์ด๋ฒคํธ๋ฅผ ์๋ฆฌ๊ธฐ ์ํด ์ฌ์ฉ๋๋
- ๊ธ๋ก๋ฒ ๋ฐ์ดํฐ, ๋ ๋ฐ์ดํฐ๊ฐ์ ์ํธ์์ฉ์ผ๋ก ๋ณผ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ณ์ ์์๋๋ก
- ์ผ์ด๋จ์ ๋ถ๋ช
ํ ํ๊ธฐ ์ํด, ํ๋ก์ธ์ค๋ฅผ ์ ์ ๋ค๊ฒ ํ๋ ๊ธฐ๋ฅ๊ณผ ๊นจ์ฐ๋ ๊ธฐ๋ฅ์
- ๋ช๊ฐ์ง ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํฉ๋๋ค.
- ๋จผ์ , ์ ์ ์ฌ์ฐ๋ ์ชฝ์ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ๋ฐ๋ฆ
๋๋ค:
- for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (event_indicated)
- break;
- schedule();
- }
- set_current_state() ์ ์ํด, ํ์คํฌ ์ํ๊ฐ ๋ฐ๋ ํ ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ
- ์๋์ผ๋ก ์ฝ์
๋ฉ๋๋ค:
- CPU 1
- ===============================
- set_current_state();
- smp_store_mb();
- STORE current->state
- <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด>
- LOAD event_indicated
- set_current_state() ๋ ๋ค์์ ๊ฒ๋ค๋ก ๊ฐ์ธ์ง ์๋ ์์ต๋๋ค:
- prepare_to_wait();
- prepare_to_wait_exclusive();
- ์ด๊ฒ๋ค ์ญ์ ์ํ๋ฅผ ์ค์ ํ ํ ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฝ์
ํฉ๋๋ค.
- ์์ ์ ์ฒด ์ํ์ค๋ ๋ค์๊ณผ ๊ฐ์ ํจ์๋ค๋ก ํ๋ฒ์ ์ํ ๊ฐ๋ฅํ๋ฐ, ์ด๊ฒ๋ค์ ๋ชจ๋
- ์ฌ๋ฐ๋ฅธ ์ฅ์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฝ์
ํฉ๋๋ค:
- wait_event();
- wait_event_interruptible();
- wait_event_interruptible_exclusive();
- wait_event_interruptible_timeout();
- wait_event_killable();
- wait_event_timeout();
- wait_on_bit();
- wait_on_bit_lock();
- ๋๋ฒ์งธ๋ก, ๊นจ์ฐ๊ธฐ๋ฅผ ์ํํ๋ ์ฝ๋๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋๋ค:
- event_indicated = 1;
- wake_up(&event_wait_queue);
- ๋๋:
- event_indicated = 1;
- wake_up_process(event_daemon);
- wake_up() ๋ฅ์ ์ํด ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ๋ดํฌ๋ฉ๋๋ค. ๋ง์ฝ ๊ทธ๊ฒ๋ค์ด ๋ญ๊ฐ๋ฅผ
- ๊นจ์ด๋ค๋ฉด์. ์ด ๋ฐฐ๋ฆฌ์ด๋ ํ์คํฌ ์ํ๊ฐ ์ง์์ง๊ธฐ ์ ์ ์ํ๋๋ฏ๋ก, ์ด๋ฒคํธ๋ฅผ
- ์๋ฆฌ๊ธฐ ์ํ STORE ์ ํ์คํฌ ์ํ๋ฅผ TASK_RUNNING ์ผ๋ก ์ค์ ํ๋ STORE ์ฌ์ด์
- ์์นํ๊ฒ ๋ฉ๋๋ค.
- CPU 1 CPU 2
- =============================== ===============================
- set_current_state(); STORE event_indicated
- smp_store_mb(); wake_up();
- STORE current->state <์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด>
- <๋ฒ์ฉ ๋ฐฐ๋ฆฌ์ด> STORE current->state
- LOAD event_indicated
- ํ๋ฒ๋ ๋งํฉ๋๋ค๋ง, ์ด ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์ด ์ฝ๋๊ฐ ์ ๋ง๋ก ๋ญ๊ฐ๋ฅผ ๊นจ์ธ ๋์๋ง
- ์คํ๋ฉ๋๋ค. ์ด๊ฑธ ์ค๋ช
ํ๊ธฐ ์ํด, X ์ Y ๋ ๋ชจ๋ 0 ์ผ๋ก ์ด๊ธฐํ ๋์ด ์๋ค๋ ๊ฐ์
- ํ์ ์๋์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2
- =============================== ===============================
- X = 1; STORE event_indicated
- smp_mb(); wake_up();
- Y = 1; wait_event(wq, Y == 1);
- wake_up(); load from Y sees 1, no memory barrier
- load from X might see 0
- ์ ์์ ์์์ ๊ฒฝ์ฐ์ ๋ฌ๋ฆฌ ๊นจ์ฐ๊ธฐ๊ฐ ์ ๋ง๋ก ํํด์ก๋ค๋ฉด, CPU 2 ์ X ๋ก๋๋ 1 ์
- ๋ณธ๋ค๊ณ ๋ณด์ฅ๋ ์ ์์ ๊ฒ๋๋ค.
- ์ฌ์ฉ ๊ฐ๋ฅํ ๊นจ์ฐ๊ธฐ๋ฅ ํจ์๋ค๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ค์ด ์์ต๋๋ค:
- complete();
- wake_up();
- wake_up_all();
- wake_up_bit();
- wake_up_interruptible();
- wake_up_interruptible_all();
- wake_up_interruptible_nr();
- wake_up_interruptible_poll();
- wake_up_interruptible_sync();
- wake_up_interruptible_sync_poll();
- wake_up_locked();
- wake_up_locked_poll();
- wake_up_nr();
- wake_up_poll();
- wake_up_process();
- [!] ์ ์ฌ์ฐ๋ ์ฝ๋์ ๊นจ์ฐ๋ ์ฝ๋์ ๋ดํฌ๋๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ค์ ๊นจ์ฐ๊ธฐ ์ ์
- ์ด๋ฃจ์ด์ง ์คํ ์ด๋ฅผ ์ ์ฌ์ฐ๋ ์ฝ๋๊ฐ set_current_state() ๋ฅผ ํธ์ถํ ํ์ ํํ๋
- ๋ก๋์ ๋ํด ์์๋ฅผ ๋ง์ถ์ง _์๋๋ค๋_ ์ ์ ๊ธฐ์ตํ์ธ์. ์๋ฅผ ๋ค์ด, ์ ์ฌ์ฐ๋
- ์ฝ๋๊ฐ ๋ค์๊ณผ ๊ฐ๊ณ :
- set_current_state(TASK_INTERRUPTIBLE);
- if (event_indicated)
- break;
- __set_current_state(TASK_RUNNING);
- do_something(my_data);
- ๊นจ์ฐ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค๋ฉด:
- my_data = value;
- event_indicated = 1;
- wake_up(&event_wait_queue);
- event_indecated ์์ ๋ณ๊ฒฝ์ด ์ ์ฌ์ฐ๋ ์ฝ๋์๊ฒ my_data ์์ ๋ณ๊ฒฝ ํ์ ์ด๋ฃจ์ด์ง
- ๊ฒ์ผ๋ก ์ธ์ง๋ ๊ฒ์ด๋ผ๋ ๋ณด์ฅ์ด ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ ์์ชฝ ์ฝ๋ ๋ชจ๋ ๊ฐ๊ฐ์
- ๋ฐ์ดํฐ ์ก์ธ์ค ์ฌ์ด์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ง์ ์ณ์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ ์์ ์ฌ์ฐ๋
- ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด:
- set_current_state(TASK_INTERRUPTIBLE);
- if (event_indicated) {
- smp_rmb();
- do_something(my_data);
- }
- ๊ทธ๋ฆฌ๊ณ ๊นจ์ฐ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ๋์ด์ผ ํฉ๋๋ค:
- my_data = value;
- smp_wmb();
- event_indicated = 1;
- wake_up(&event_wait_queue);
- ๊ทธ์ธ์ ํจ์๋ค
- -------------
- ๊ทธ์ธ์ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ๋ ํจ์๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- (*) schedule() ๊ณผ ๊ทธ ์ ์ฌํ ๊ฒ๋ค์ด ์์ ํ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํฉ๋๋ค.
- ==============================
- CPU ๊ฐ ACQUIRING ๋ฐฐ๋ฆฌ์ด์ ํจ๊ณผ
- ==============================
- SMP ์์คํ
์์์ ๋ฝ ๊ธฐ๋ฅ๋ค์ ๋์ฑ ๊ฐ๋ ฅํ ํํ์ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค: ์ด
- ๋ฐฐ๋ฆฌ์ด๋ ๋์ผํ ๋ฝ์ ์ฌ์ฉํ๋ ๋ค๋ฅธ CPU ๋ค์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ์์์๋ ์ํฅ์
- ๋ผ์นฉ๋๋ค.
- ACQUIRE VS ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค
- ------------------------
- ๋ค์์ ์๋ฅผ ์๊ฐํด ๋ด
์๋ค: ์์คํ
์ ๋๊ฐ์ ์คํ๋ฝ (M) ๊ณผ (Q), ๊ทธ๋ฆฌ๊ณ ์ธ๊ฐ์ CPU
- ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค; ์ฌ๊ธฐ์ ๋ค์์ ์ด๋ฒคํธ ์ํ์ค๊ฐ ๋ฐ์ํฉ๋๋ค:
- CPU 1 CPU 2
- =============================== ===============================
- WRITE_ONCE(*A, a); WRITE_ONCE(*E, e);
- ACQUIRE M ACQUIRE Q
- WRITE_ONCE(*B, b); WRITE_ONCE(*F, f);
- WRITE_ONCE(*C, c); WRITE_ONCE(*G, g);
- RELEASE M RELEASE Q
- WRITE_ONCE(*D, d); WRITE_ONCE(*H, h);
- *A ๋ก์ ์ก์ธ์ค๋ถํฐ *H ๋ก์ ์ก์ธ์ค๊น์ง๊ฐ ์ด๋ค ์์๋ก CPU 3 ์๊ฒ ๋ณด์ฌ์ง์ง์
- ๋ํด์๋ ๊ฐ CPU ์์์ ๋ฝ ์ฌ์ฉ์ ์ํด ๋ดํฌ๋์ด ์๋ ์ ์ฝ์ ์ ์ธํ๊ณ ๋ ์ด๋ค
- ๋ณด์ฅ๋ ์กด์ฌํ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, CPU 3 ์๊ฒ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๋ณด์ฌ์ง๋
- ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค:
- *E, ACQUIRE M, ACQUIRE Q, *G, *C, *F, *A, *B, RELEASE Q, *D, *H, RELEASE M
- ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ด์ง๋ ์์ ๊ฒ๋๋ค:
- *B, *C or *D preceding ACQUIRE M
- *A, *B or *C following RELEASE M
- *F, *G or *H preceding ACQUIRE Q
- *E, *F or *G following RELEASE Q
- ACQUIRE VS I/O ์ก์ธ์ค
- ----------------------
- ํน์ ํ (ํนํ NUMA ๊ฐ ๊ด๋ จ๋) ํ๊ฒฝ ํ์์ ๋๊ฐ์ CPU ์์ ๋์ผํ ์คํ๋ฝ์ผ๋ก
- ๋ณดํธ๋๋ ๋๊ฐ์ ํฌ๋ฆฌํฐ์ปฌ ์น์
์์ I/O ์ก์ธ์ค๋ PCI ๋ธ๋ฆฟ์ง์ ๊ฒน์ณ์ง I/O
- ์ก์ธ์ค๋ก ๋ณด์ผ ์ ์๋๋ฐ, PCI ๋ธ๋ฆฟ์ง๋ ์บ์ ์ผ๊ด์ฑ ํ๋กํ ์ฝ๊ณผ ํฉ์ ๋ง์ถฐ์ผ ํ
- ์๋ฌด๊ฐ ์์ผ๋ฏ๋ก, ํ์ํ ์ฝ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ์์ฒญ๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
- ์๋ฅผ ๋ค์ด์:
- CPU 1 CPU 2
- =============================== ===============================
- spin_lock(Q)
- writel(0, ADDR)
- writel(1, DATA);
- spin_unlock(Q);
- spin_lock(Q);
- writel(4, ADDR);
- writel(5, DATA);
- spin_unlock(Q);
- ๋ PCI ๋ธ๋ฆฟ์ง์ ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ์ ์์ต๋๋ค:
- STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
- ์ด๋ ๊ฒ ๋๋ฉด ํ๋์จ์ด์ ์ค๋์์ ์ผ์ผํฌ ์ ์์ต๋๋ค.
- ์ด๋ฐ ๊ฒฝ์ฐ์ ์ก์๋ ์คํ๋ฝ์ ๋ด๋ ค๋๊ธฐ ์ ์ mmiowb() ๋ฅผ ์ํํด์ผ ํ๋๋ฐ, ์๋ฅผ
- ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- CPU 1 CPU 2
- =============================== ===============================
- spin_lock(Q)
- writel(0, ADDR)
- writel(1, DATA);
- mmiowb();
- spin_unlock(Q);
- spin_lock(Q);
- writel(4, ADDR);
- writel(5, DATA);
- mmiowb();
- spin_unlock(Q);
- ์ด ์ฝ๋๋ CPU 1 ์์ ์์ฒญ๋ ๋๊ฐ์ ์คํ ์ด๊ฐ PCI ๋ธ๋ฆฟ์ง์ CPU 2 ์์ ์์ฒญ๋
- ์คํ ์ด๋ค๋ณด๋ค ๋จผ์ ๋ณด์ฌ์ง์ ๋ณด์ฅํฉ๋๋ค.
- ๋ํ, ๊ฐ์ ๋๋ฐ์ด์ค์์ ์คํ ์ด๋ฅผ ์ด์ด ๋ก๋๊ฐ ์ํ๋๋ฉด ์ด ๋ก๋๋ ๋ก๋๊ฐ ์ํ๋๊ธฐ
- ์ ์ ์คํ ์ด๊ฐ ์๋ฃ๋๊ธฐ๋ฅผ ๊ฐ์ ํ๋ฏ๋ก mmiowb() ์ ํ์๊ฐ ์์ด์ง๋๋ค:
- CPU 1 CPU 2
- =============================== ===============================
- spin_lock(Q)
- writel(0, ADDR)
- a = readl(DATA);
- spin_unlock(Q);
- spin_lock(Q);
- writel(4, ADDR);
- b = readl(DATA);
- spin_unlock(Q);
- ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ Documenataion/DocBook/deviceiobook.tmpl ์ ์ฐธ๊ณ ํ์ธ์.
- =========================
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ๊ณณ
- =========================
- ์ค๋ น SMP ์ปค๋์ ์ฌ์ฉํ๋๋ผ๋ ์ฑ๊ธ ์ฐ๋ ๋๋ก ๋์ํ๋ ์ฝ๋๋ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๋
- ๊ฒ์ผ๋ก ๋ณด์ฌ์ง ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ํ๋ฒํ ์์คํ
์ด์์ค์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
์ฌ๋ฐฐ์น๋
- ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ํ์ง๋ง, ์ฌ๋ฐฐ์น๊ฐ ๋ฌธ์ ๊ฐ _๋ ์ ์๋_ ๋ค๊ฐ์ง
- ํ๊ฒฝ์ด ์์ต๋๋ค:
- (*) ํ๋ก์ธ์๊ฐ ์ํธ ์์ฉ.
- (*) ์ดํ ๋ฏน ์คํผ๋ ์ด์
.
- (*) ๋๋ฐ์ด์ค ์ก์ธ์ค.
- (*) ์ธํฐ๋ฝํธ.
- ํ๋ก์ธ์๊ฐ ์ํธ ์์ฉ
- --------------------
- ๋๊ฐ ์ด์์ ํ๋ก์ธ์๋ฅผ ๊ฐ์ง ์์คํ
์ด ์๋ค๋ฉด, ์์คํ
์ ๋๊ฐ ์ด์์ CPU ๋ ๋์์
- ๊ฐ์ ๋ฐ์ดํฐ์ ๋ํ ์์
์ ํ ์ ์์ต๋๋ค. ์ด๋ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๊ณ ,
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ผ๋ฐ์ ๋ฐฉ๋ฒ์ ๋ฝ์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ํ์ง๋ง, ๋ฝ์ ์๋นํ
- ๋น์ฉ์ด ๋น์ธ์ ๊ฐ๋ฅํ๋ฉด ๋ฝ์ ์ฌ์ฉํ์ง ์๊ณ ์ผ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ซ์ต๋๋ค. ์ด๋ฐ
- ๊ฒฝ์ฐ, ๋ CPU ๋ชจ๋์ ์ํฅ์ ๋ผ์น๋ ์คํผ๋ ์ด์
๋ค์ ์ค๋์์ ๋ง๊ธฐ ์ํด ์ ์คํ๊ฒ
- ์์๊ฐ ๋ง์ถฐ์ ธ์ผ ํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, R/W ์ธ๋งํฌ์ด์ ๋๋ฆฐ ์ํ๊ฒฝ๋ก (slow path) ๋ฅผ ์๊ฐํด ๋ด
์๋ค.
- ์ธ๋งํฌ์ด๋ฅผ ์ํด ๋๊ธฐ๋ฅผ ํ๋ ํ๋์ ํ๋ก์ธ์ค๊ฐ ์์ ์ ์คํ ์ค ์ผ๋ถ๋ฅผ ์ด
- ์ธ๋งํฌ์ด์ ๋๊ธฐ ํ๋ก์ธ์ค ๋ฆฌ์คํธ์ ๋งํฌํ ์ฑ๋ก ์์ต๋๋ค:
- struct rw_semaphore {
- ...
- spinlock_t lock;
- struct list_head waiters;
- };
- struct rwsem_waiter {
- struct list_head list;
- struct task_struct *task;
- };
- ํน์ ๋๊ธฐ ์ํ ํ๋ก์ธ์ค๋ฅผ ๊นจ์ฐ๊ธฐ ์ํด, up_read() ๋ up_write() ํจ์๋ ๋ค์๊ณผ
- ๊ฐ์ ์ผ์ ํฉ๋๋ค:
- (1) ๋ค์ ๋๊ธฐ ์ํ ํ๋ก์ธ์ค ๋ ์ฝ๋๋ ์ด๋์๋์ง ์๊ธฐ ์ํด ์ด ๋๊ธฐ ์ํ
- ํ๋ก์ธ์ค ๋ ์ฝ๋์ next ํฌ์ธํฐ๋ฅผ ์ฝ์ต๋๋ค;
- (2) ์ด ๋๊ธฐ ์ํ ํ๋ก์ธ์ค์ task ๊ตฌ์กฐ์ฒด๋ก์ ํฌ์ธํฐ๋ฅผ ์ฝ์ต๋๋ค;
- (3) ์ด ๋๊ธฐ ์ํ ํ๋ก์ธ์ค๊ฐ ์ธ๋งํฌ์ด๋ฅผ ํ๋ํ์์ ์๋ฆฌ๊ธฐ ์ํด task
- ํฌ์ธํฐ๋ฅผ ์ด๊ธฐํ ํฉ๋๋ค;
- (4) ํด๋น ํ์คํฌ์ ๋ํด wake_up_process() ๋ฅผ ํธ์ถํฉ๋๋ค; ๊ทธ๋ฆฌ๊ณ
- (5) ํด๋น ๋๊ธฐ ์ํ ํ๋ก์ธ์ค์ task ๊ตฌ์กฐ์ฒด๋ฅผ ์ก๊ณ ์๋ ๋ ํผ๋ฐ์ค๋ฅผ ํด์ ํฉ๋๋ค.
- ๋ฌ๋ฆฌ ๋งํ์๋ฉด, ๋ค์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ์ํํด์ผ ํฉ๋๋ค:
- LOAD waiter->list.next;
- LOAD waiter->task;
- STORE waiter->task;
- CALL wakeup
- RELEASE task
- ๊ทธ๋ฆฌ๊ณ ์ด ์ด๋ฒคํธ๋ค์ด ๋ค๋ฅธ ์์๋ก ์ํ๋๋ค๋ฉด, ์ค๋์์ด ์ผ์ด๋ ์ ์์ต๋๋ค.
- ํ๋ฒ ์ธ๋งํฌ์ด์ ๋๊ธฐ์ค์ ๋ค์ด๊ฐ๊ณ ์ธ๋งํฌ์ด ๋ฝ์ ๋์๋ค๋ฉด, ํด๋น ๋๊ธฐ ํ๋ก์ธ์ค๋
- ๋ฝ์ ๋ค์๋ ์ก์ง ์์ต๋๋ค; ๋์ ์์ ์ task ํฌ์ธํฐ๊ฐ ์ด๊ธฐํ ๋๊ธธ ๊ธฐ๋ค๋ฆฝ๋๋ค.
- ๊ทธ ๋ ์ฝ๋๋ ๋๊ธฐ ํ๋ก์ธ์ค์ ์คํ์ ์๊ธฐ ๋๋ฌธ์, ๋ฆฌ์คํธ์ next ํฌ์ธํฐ๊ฐ ์ฝํ์ง๊ธฐ
- _์ ์_ task ํฌ์ธํฐ๊ฐ ์ง์์ง๋ค๋ฉด, ๋ค๋ฅธ CPU ๋ ํด๋น ๋๊ธฐ ํ๋ก์ธ์ค๋ฅผ ์์ํด ๋ฒ๋ฆฌ๊ณ
- up*() ํจ์๊ฐ next ํฌ์ธํฐ๋ฅผ ์ฝ๊ธฐ ์ ์ ๋๊ธฐ ํ๋ก์ธ์ค์ ์คํ์ ๋ง๊ตฌ ๊ฑด๋๋ฆด ์
- ์์ต๋๋ค.
- ๊ทธ๋ ๊ฒ ๋๋ฉด ์์ ์ด๋ฒคํธ ์ํ์ค์ ์ด๋ค ์ผ์ด ์ผ์ด๋๋์ง ์๊ฐํด ๋ณด์ฃ :
- CPU 1 CPU 2
- =============================== ===============================
- down_xxx()
- Queue waiter
- Sleep
- up_yyy()
- LOAD waiter->task;
- STORE waiter->task;
- Woken up by other event
- <preempt>
- Resume processing
- down_xxx() returns
- call foo()
- foo() clobbers *waiter
- </preempt>
- LOAD waiter->list.next;
- --- OOPS ---
- ์ด ๋ฌธ์ ๋ ์ธ๋งํฌ์ด ๋ฝ์ ์ฌ์ฉ์ผ๋ก ํด๊ฒฐ๋ ์๋ ์๊ฒ ์ง๋ง, ๊ทธ๋ ๊ฒ ๋๋ฉด ๊นจ์ด๋ ํ์
- down_xxx() ํจ์๊ฐ ๋ถํ์ํ๊ฒ ์คํ๋ฝ์ ๋๋ค์ ์ป์ด์ผ๋ง ํฉ๋๋ค.
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ฒ์ฉ SMP ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋๋ค:
- LOAD waiter->list.next;
- LOAD waiter->task;
- smp_mb();
- STORE waiter->task;
- CALL wakeup
- RELEASE task
- ์ด ๊ฒฝ์ฐ์, ๋ฐฐ๋ฆฌ์ด๋ ์์คํ
์ ๋๋จธ์ง CPU ๋ค์๊ฒ ๋ชจ๋ ๋ฐฐ๋ฆฌ์ด ์์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๊ฐ
- ๋ฐฐ๋ฆฌ์ด ๋ค์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ณด๋ค ์์ ์ผ์ด๋ ๊ฒ์ผ๋ก ๋ณด์ด๊ฒ ๋ง๋ญ๋๋ค. ๋ฐฐ๋ฆฌ์ด ์์
- ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ค์ด ๋ฐฐ๋ฆฌ์ด ๋ช
๋ น ์์ฒด๊ฐ ์๋ฃ๋๋ ์์ ๊น์ง ์๋ฃ๋๋ค๊ณ ๋ ๋ณด์ฅํ์ง
- _์์ต๋๋ค_.
- (์ด๊ฒ ๋ฌธ์ ๊ฐ ๋์ง ์์) ๋จ์ผ ํ๋ก์ธ์ ์์คํ
์์ smp_mb() ๋ ์ค์ ๋ก๋ ๊ทธ์
- ์ปดํ์ผ๋ฌ๊ฐ CPU ์์์์ ์์๋ฅผ ๋ฐ๊พธ๊ฑฐ๋ ํ์ง ์๊ณ ์ฃผ์ด์ง ์์๋๋ก ๋ช
๋ น์
- ๋ด๋ฆฌ๋๋ก ํ๋ ์ปดํ์ผ๋ฌ ๋ฐฐ๋ฆฌ์ด์ผ ๋ฟ์
๋๋ค. ์ค์ง ํ๋์ CPU ๋ง ์์ผ๋, CPU ์
- ์์กด์ฑ ์์ ๋ก์ง์ด ๊ทธ ์ธ์ ๋ชจ๋ ๊ฒ์ ์์์ ์ฒ๋ฆฌํ ๊ฒ๋๋ค.
- ์ดํ ๋ฏน ์คํผ๋ ์ด์
- -----------------
- ์ดํ ๋ฏน ์คํผ๋ ์ด์
์ ๊ธฐ์ ์ ์ผ๋ก ํ๋ก์ธ์๊ฐ ์ํธ์์ฉ์ผ๋ก ๋ถ๋ฅ๋๋ฉฐ ๊ทธ ์ค ์ผ๋ถ๋
- ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ๊ณ ๋ ์ผ๋ถ๋ ๋ดํฌํ์ง ์์ง๋ง, ์ปค๋์์ ์๋นํ
- ์์กด์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ธฐ๋ฅ ์ค ํ๋์
๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ์ ์ด๋ค ์ํ๋ฅผ ์์ ํ๊ณ ํด๋น ์ํ์ ๋ํ (์์ ์ ๋๋ ์ต์ ์) ์ ๋ณด๋ฅผ
- ๋ฆฌํดํ๋ ์ดํ ๋ฏน ์คํผ๋ ์ด์
์ ๋ชจ๋ SMP-์กฐ๊ฑด์ ๋ฒ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด(smp_mb())๋ฅผ
- ์ค์ ์คํผ๋ ์ด์
์ ์๊ณผ ๋ค์ ๋ดํฌํฉ๋๋ค. ์ด๋ฐ ์คํผ๋ ์ด์
์ ๋ค์์ ๊ฒ๋ค์
- ํฌํจํฉ๋๋ค:
- xchg();
- atomic_xchg(); atomic_long_xchg();
- atomic_inc_return(); atomic_long_inc_return();
- atomic_dec_return(); atomic_long_dec_return();
- atomic_add_return(); atomic_long_add_return();
- atomic_sub_return(); atomic_long_sub_return();
- atomic_inc_and_test(); atomic_long_inc_and_test();
- atomic_dec_and_test(); atomic_long_dec_and_test();
- atomic_sub_and_test(); atomic_long_sub_and_test();
- atomic_add_negative(); atomic_long_add_negative();
- test_and_set_bit();
- test_and_clear_bit();
- test_and_change_bit();
- /* exchange ์กฐ๊ฑด์ด ์ฑ๊ณตํ ๋ */
- cmpxchg();
- atomic_cmpxchg(); atomic_long_cmpxchg();
- atomic_add_unless(); atomic_long_add_unless();
- ์ด๊ฒ๋ค์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ํจ๊ณผ๊ฐ ํ์ํ ACQUIRE ๋ถ๋ฅ์ RELEASE ๋ถ๋ฅ ์คํผ๋ ์ด์
๋ค์
- ๊ตฌํํ ๋, ๊ทธ๋ฆฌ๊ณ ๊ฐ์ฒด ํด์ ๋ฅผ ์ํด ๋ ํผ๋ฐ์ค ์นด์ดํฐ๋ฅผ ์กฐ์ ํ ๋, ์๋ฌต์ ๋ฉ๋ชจ๋ฆฌ
- ๋ฐฐ๋ฆฌ์ด ํจ๊ณผ๊ฐ ํ์ํ ๊ณณ ๋ฑ์ ์ฌ์ฉ๋ฉ๋๋ค.
- ๋ค์์ ์คํผ๋ ์ด์
๋ค์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ์ง _์๊ธฐ_ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ ์
- ์์ง๋ง, RELEASE ๋ถ๋ฅ์ ์คํผ๋ ์ด์
๋ค๊ณผ ๊ฐ์ ๊ฒ๋ค์ ๊ตฌํํ ๋ ์ฌ์ฉ๋ ์๋
- ์์ต๋๋ค:
- atomic_set();
- set_bit();
- clear_bit();
- change_bit();
- ์ด๊ฒ๋ค์ ์ฌ์ฉํ ๋์๋ ํ์ํ๋ค๋ฉด ์ ์ ํ (์๋ฅผ ๋ค๋ฉด smp_mb__before_atomic()
- ๊ฐ์) ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ๋ช
์์ ์ผ๋ก ํจ๊ป ์ฌ์ฉ๋์ด์ผ ํฉ๋๋ค.
- ์๋์ ๊ฒ๋ค๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌํ์ง _์๊ธฐ_ ๋๋ฌธ์, ์ผ๋ถ ํ๊ฒฝ์์๋ (์๋ฅผ
- ๋ค๋ฉด smp_mb__before_atomic() ๊ณผ ๊ฐ์) ๋ช
์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ฌ์ฉ์ด ํ์ํฉ๋๋ค.
- atomic_add();
- atomic_sub();
- atomic_inc();
- atomic_dec();
- ์ด๊ฒ๋ค์ด ํต๊ณ ์์ฑ์ ์ํด ์ฌ์ฉ๋๋ค๋ฉด, ๊ทธ๋ฆฌ๊ณ ํต๊ณ ๋ฐ์ดํฐ ์ฌ์ด์ ๊ด๊ณ๊ฐ ์กด์ฌํ์ง
- ์๋๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ํ์์น ์์ ๊ฒ๋๋ค.
- ๊ฐ์ฒด์ ์๋ช
์ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ ํผ๋ฐ์ค ์นด์ดํ
๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ค๋ฉด, ๋ ํผ๋ฐ์ค
- ์นด์ดํฐ๋ ๋ฝ์ผ๋ก ๋ณดํธ๋๋ ์น์
์์๋ง ์กฐ์ ๋๊ฑฐ๋ ํธ์ถํ๋ ์ชฝ์ด ์ด๋ฏธ ์ถฉ๋ถํ
- ๋ ํผ๋ฐ์ค๋ฅผ ์ก๊ณ ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์๋ง ํ์ ์์ ๊ฒ๋๋ค.
- ๋ง์ฝ ์ด๋ค ๋ฝ์ ๊ตฌ์ฑํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค๋ฉด, ๋ฝ ๊ด๋ จ ๋์์ ์ผ๋ฐ์ ์ผ๋ก ์์
์ ํน์
- ์์๋๋ก ์งํํด์ผ ํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ์ ์์ต๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก, ๊ฐ ์ฌ์ฉ์ฒ์์๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ์ง ์๋์ง ์ถฉ๋ถํ ๊ณ ๋ คํด์ผ
- ํฉ๋๋ค.
- ์๋์ ์คํผ๋ ์ด์
๋ค์ ํน๋ณํ ๋ฝ ๊ด๋ จ ๋์๋ค์
๋๋ค:
- test_and_set_bit_lock();
- clear_bit_unlock();
- __clear_bit_unlock();
- ์ด๊ฒ๋ค์ ACQUIRE ๋ฅ์ RELEASE ๋ฅ์ ์คํผ๋ ์ด์
๋ค์ ๊ตฌํํฉ๋๋ค. ๋ฝ ๊ด๋ จ ๋๊ตฌ๋ฅผ
- ๊ตฌํํ ๋์๋ ์ด๊ฒ๋ค์ ์ข ๋ ์ ํธํ๋ ํธ์ด ๋์๋ฐ, ์ด๊ฒ๋ค์ ๊ตฌํ์ ๋ง์
- ์ํคํ
์ณ์์ ์ต์ ํ ๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
- [!] ์ด๋ฐ ์ํฉ์ ์ฌ์ฉํ ์ ์๋ ํน์ํ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋๊ตฌ๋ค์ด ์์ต๋๋ค๋ง, ์ผ๋ถ
- CPU ์์๋ ์ฌ์ฉ๋๋ ์ดํ ๋ฏน ์ธ์คํธ๋ญ์
์์ฒด์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ๋ดํฌ๋์ด ์์ด์
- ์ดํ ๋ฏน ์คํผ๋ ์ด์
๊ณผ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ ๋ถํ์ํ ์ผ์ด ๋ ์
- ์๋๋ฐ, ๊ทธ๋ฐ ๊ฒฝ์ฐ์ ์ด ํน์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋๊ตฌ๋ค์ no-op ์ด ๋์ด ์ค์ง์ ์ผ๋ก
- ์๋ฌด์ผ๋ ํ์ง ์์ต๋๋ค.
- ๋ ๋ง์ ๋ด์ฉ์ ์ํด์ Documentation/atomic_ops.txt ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
- ๋๋ฐ์ด์ค ์ก์ธ์ค
- ---------------
- ๋ง์ ๋๋ฐ์ด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋งคํ ๊ธฐ๋ฒ์ผ๋ก ์ ์ด๋ ์ ์๋๋ฐ, ๊ทธ๋ ๊ฒ ์ ์ด๋๋
- ๋๋ฐ์ด์ค๋ CPU ์๋ ๋จ์ง ํน์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์งํฉ์ฒ๋ผ ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ๋๋ผ์ด๋ฒ๋
- ๊ทธ๋ฐ ๋๋ฐ์ด์ค๋ฅผ ์ ์ดํ๊ธฐ ์ํด ์ ํํ ์ฌ๋ฐ๋ฅธ ์์๋ก ์ฌ๋ฐ๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ฅผ
- ๋ง๋ค์ด์ผ ํฉ๋๋ค.
- ํ์ง๋ง, ์ก์ธ์ค๋ค์ ์ฌ๋ฐฐ์น ํ๊ฑฐ๋ ์กฐํฉํ๊ฑฐ๋ ๋ณํฉํ๋๊ฒ ๋ ํจ์จ์ ์ด๋ผ ํ๋จํ๋
- ์๋ฆฌํ CPU ๋ ์ปดํ์ผ๋ฌ๋ค์ ์ฌ์ฉํ๋ฉด ๋๋ผ์ด๋ฒ ์ฝ๋์ ์กฐ์ฌ์ค๋ฝ๊ฒ ์์ ๋ง์ถฐ์ง
- ์ก์ธ์ค๋ค์ด ๋๋ฐ์ด์ค์๋ ์์ฒญ๋ ์์๋๋ก ๋์ฐฉํ์ง ๋ชปํ๊ฒ ํ ์ ์๋ - ๋๋ฐ์ด์ค๊ฐ
- ์ค๋์์ ํ๊ฒ ํ - ์ ์ฌ์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ต๋๋ค.
- ๋ฆฌ๋
์ค ์ปค๋ ๋ด๋ถ์์, I/O ๋ ์ด๋ป๊ฒ ์ก์ธ์ค๋ค์ ์ ์ ํ ์์ฐจ์ ์ด๊ฒ ๋ง๋ค ์ ์๋์ง
- ์๊ณ ์๋, - inb() ๋ writel() ๊ณผ ๊ฐ์ - ์ ์ ํ ์ก์ธ์ค ๋ฃจํด์ ํตํด ์ด๋ฃจ์ด์ ธ์ผ๋ง
- ํฉ๋๋ค. ์ด๊ฒ๋ค์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ์๋ ๋ช
์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ์ ํจ๊ป ์ฌ์ฉ๋ ํ์๊ฐ
- ์์ต๋๋ค๋ง, ๋ค์์ ๋๊ฐ์ง ์ํฉ์์๋ ๋ช
์์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ์ ์์ต๋๋ค:
- (1) ์ผ๋ถ ์์คํ
์์ I/O ์คํ ์ด๋ ๋ชจ๋ CPU ์ ์ผ๊ด๋๊ฒ ์์ ๋ง์ถฐ์ง์ง ์๋๋ฐ,
- ๋ฐ๋ผ์ _๋ชจ๋ _ ์ผ๋ฐ์ ์ธ ๋๋ผ์ด๋ฒ๋ค์ ๋ฝ์ด ์ฌ์ฉ๋์ด์ผ๋ง ํ๊ณ ์ด ํฌ๋ฆฌํฐ์ปฌ
- ์น์
์ ๋น ์ ธ๋์ค๊ธฐ ์ ์ mmiowb() ๊ฐ ๊ผญ ํธ์ถ๋์ด์ผ ํฉ๋๋ค.
- (2) ๋ง์ฝ ์ก์ธ์ค ํจ์๋ค์ด ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ์์ฑ์ ๊ฐ๋ I/O ๋ฉ๋ชจ๋ฆฌ ์๋์ฐ๋ฅผ
- ์ฌ์ฉํ๋ค๋ฉด, ์์๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด์ _mandatory_ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํฉ๋๋ค.
- ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ Documentation/DocBook/deviceiobook.tmpl ์ ์ฐธ๊ณ ํ์ญ์์ค.
- ์ธํฐ๋ฝํธ
- --------
- ๋๋ผ์ด๋ฒ๋ ์์ ์ ์ธํฐ๋ฝํธ ์๋น์ค ๋ฃจํด์ ์ํด ์ธํฐ๋ฝํธ ๋นํ ์ ์๊ธฐ ๋๋ฌธ์
- ๋๋ผ์ด๋ฒ์ ์ด ๋ ๋ถ๋ถ์ ์๋ก์ ๋๋ฐ์ด์ค ์ ์ด ๋๋ ์ก์ธ์ค ๋ถ๋ถ๊ณผ ์ํธ ๊ฐ์ญํ ์
- ์์ต๋๋ค.
- ์ค์ค๋ก์๊ฒ ์ธํฐ๋ฝํธ ๋นํ๋ ๊ฑธ ๋ถ๊ฐ๋ฅํ๊ฒ ํ๊ณ , ๋๋ผ์ด๋ฒ์ ํฌ๋ฆฌํฐ์ปฌํ
- ์คํผ๋ ์ด์
๋ค์ ๋ชจ๋ ์ธํฐ๋ฝํธ๊ฐ ๋ถ๊ฐ๋ฅํ๊ฒ ๋ ์์ญ์ ์ง์ด๋ฃ๊ฑฐ๋ ํ๋ ๋ฐฉ๋ฒ (๋ฝ์
- ํ ํํ) ์ผ๋ก ์ด๋ฐ ์ํธ ๊ฐ์ญ์ - ์ต์ํ ๋ถ๋ถ์ ์ผ๋ก๋ผ๋ - ์ค์ผ ์ ์์ต๋๋ค.
- ๋๋ผ์ด๋ฒ์ ์ธํฐ๋ฝํธ ๋ฃจํด์ด ์คํ ์ค์ธ ๋์, ํด๋น ๋๋ผ์ด๋ฒ์ ์ฝ์ด๋ ๊ฐ์ CPU ์์
- ์ํ๋์ง ์์ ๊ฒ์ด๋ฉฐ, ํ์ฌ์ ์ธํฐ๋ฝํธ๊ฐ ์ฒ๋ฆฌ๋๋ ์ค์๋ ๋๋ค์ ์ธํฐ๋ฝํธ๊ฐ
- ์ผ์ด๋์ง ๋ชปํ๋๋ก ๋์ด ์์ผ๋ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ๋ ๊ทธ์ ๋ํด์๋ ๋ฝ์ ์ก์ง ์์๋
- ๋ฉ๋๋ค.
- ํ์ง๋ง, ์ด๋๋ ์ค ๋ ์ง์คํฐ์ ๋ฐ์ดํฐ ๋ ์ง์คํฐ๋ฅผ ๊ฐ๋ ์ด๋๋ท ์นด๋๋ฅผ ๋ค๋ฃจ๋
- ๋๋ผ์ด๋ฒ๋ฅผ ์๊ฐํด ๋ด
์๋ค. ๋ง์ฝ ์ด ๋๋ผ์ด๋ฒ์ ์ฝ์ด๊ฐ ์ธํฐ๋ฝํธ๋ฅผ ๋นํ์ฑํ์ํจ
- ์ฑ๋ก ์ด๋๋ท ์นด๋์ ๋ํํ๊ณ ๋๋ผ์ด๋ฒ์ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ๊ฐ ํธ์ถ๋์๋ค๋ฉด:
- LOCAL IRQ DISABLE
- writew(ADDR, 3);
- writew(DATA, y);
- LOCAL IRQ ENABLE
- <interrupt>
- writew(ADDR, 4);
- q = readw(DATA);
- </interrupt>
- ๋ง์ฝ ์์ ๊ท์น์ด ์ถฉ๋ถํ ์ํ๋์ด ์๋ค๋ฉด ๋ฐ์ดํฐ ๋ ์ง์คํฐ์์ ์คํ ์ด๋ ์ด๋๋ ์ค
- ๋ ์ง์คํฐ์ ๋๋ฒ์งธ๋ก ํํด์ง๋ ์คํ ์ด ๋ค์ ์ผ์ด๋ ์๋ ์์ต๋๋ค:
- STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA
- ๋ง์ฝ ์์ ๊ท์น์ด ์ถฉ๋ถํ ์ํ๋์ด ์๊ณ ๋ฌต์์ ์ผ๋ก๋ ๋ช
์์ ์ผ๋ก๋ ๋ฐฐ๋ฆฌ์ด๊ฐ
- ์ฌ์ฉ๋์ง ์์๋ค๋ฉด ์ธํฐ๋ฝํธ ๋นํ์ฑํ ์น์
์์ ์ผ์ด๋ ์ก์ธ์ค๊ฐ ๋ฐ๊นฅ์ผ๋ก ์์ด์
- ์ธํฐ๋ฝํธ ๋ด์์ ์ผ์ด๋ ์ก์ธ์ค์ ์์ผ ์ ์๋ค๊ณ - ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฐ๋๋ - ๊ฐ์ ํด์ผ๋ง
- ํฉ๋๋ค.
- ๊ทธ๋ฐ ์์ญ ์์์ ์ผ์ด๋๋ I/O ์ก์ธ์ค๋ค์ ์๊ฒฉํ ์์ ๊ท์น์ I/O ๋ ์ง์คํฐ์
- ๋ฌต์์ I/O ๋ฐฐ๋ฆฌ์ด๋ฅผ ํ์ฑํ๋ ๋๊ธฐ์ (synchronous) ๋ก๋ ์คํผ๋ ์ด์
์ ํฌํจํ๊ธฐ
- ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก๋ ์ด๋ฐ๊ฒ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๋ง์ฝ ์ด๊ฑธ๋ก๋ ์ถฉ๋ถ์น ์๋ค๋ฉด
- mmiowb() ๊ฐ ๋ช
์์ ์ผ๋ก ์ฌ์ฉ๋ ํ์๊ฐ ์์ต๋๋ค.
- ํ๋์ ์ธํฐ๋ฝํธ ๋ฃจํด๊ณผ ๋ณ๋์ CPU ์์ ์ํ์ค์ด๋ฉฐ ์๋ก ํต์ ์ ํ๋ ๋ ๋ฃจํด
- ์ฌ์ด์๋ ๋น์ทํ ์ํฉ์ด ์ผ์ด๋ ์ ์์ต๋๋ค. ๋ง์ฝ ๊ทธ๋ฐ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด
- ์๋ค๋ฉด, ์์๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ์ธํฐ๋ฝํธ ๋นํ์ฑํ ๋ฝ์ด ์ฌ์ฉ๋์ด์ ธ์ผ๋ง ํฉ๋๋ค.
- ======================
- ์ปค๋ I/O ๋ฐฐ๋ฆฌ์ด์ ํจ๊ณผ
- ======================
- I/O ๋ฉ๋ชจ๋ฆฌ์ ์ก์ธ์คํ ๋, ๋๋ผ์ด๋ฒ๋ ์ ์ ํ ์ก์ธ์ค ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค:
- (*) inX(), outX():
- ์ด๊ฒ๋ค์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ๋ณด๋ค๋ I/O ๊ณต๊ฐ์ ์ด์ผ๊ธฐ๋ฅผ ํ๋ ค๋ ์๋๋ก
- ๋ง๋ค์ด์ก์ต๋๋ค๋ง, ๊ทธ๊ฑด ๊ธฐ๋ณธ์ ์ผ๋ก CPU ๋ง๋ค ๋ค๋ฅธ ์ปจ์
์
๋๋ค. i386 ๊ณผ
- x86_64 ํ๋ก์ธ์๋ค์ ํน๋ณํ I/O ๊ณต๊ฐ ์ก์ธ์ค ์ฌ์ดํด๊ณผ ๋ช
๋ น์ด๋ฅผ ์ค์ ๋ก ๊ฐ์ง๊ณ
- ์์ง๋ง, ๋ค๋ฅธ ๋ง์ CPU ๋ค์๋ ๊ทธ๋ฐ ์ปจ์
์ด ์กด์ฌํ์ง ์์ต๋๋ค.
- ๋ค๋ฅธ ๊ฒ๋ค ์ค์์๋ PCI ๋ฒ์ค๊ฐ I/O ๊ณต๊ฐ ์ปจ์
์ ์ ์ํ๋๋ฐ, ์ด๋ - i386 ๊ณผ
- x86_64 ๊ฐ์ CPU ์์ - CPU ์ I/O ๊ณต๊ฐ ์ปจ์
์ผ๋ก ์ฝ๊ฒ ๋งค์น๋ฉ๋๋ค. ํ์ง๋ง,
- ๋์ฒดํ I/O ๊ณต๊ฐ์ด ์๋ CPU ์์๋ CPU ์ ๋ฉ๋ชจ๋ฆฌ ๋งต์ ๊ฐ์ I/O ๊ณต๊ฐ์ผ๋ก
- ๋งคํ๋ ์๋ ์์ต๋๋ค.
- ์ด ๊ณต๊ฐ์ผ๋ก์ ์ก์ธ์ค๋ (i386 ๋ฑ์์๋) ์์ ํ๊ฒ ๋๊ธฐํ ๋ฉ๋๋ค๋ง, ์ค๊ฐ์
- (PCI ํธ์คํธ ๋ธ๋ฆฌ์ง์ ๊ฐ์) ๋ธ๋ฆฌ์ง๋ค์ ์ด๋ฅผ ์์ ํ ๋ณด์ฅํ์ง ์์์๋
- ์์ต๋๋ค.
- ์ด๊ฒ๋ค์ ์ํธ๊ฐ์ ์์๋ ์์ ํ๊ฒ ๋ณด์ฅ๋ฉ๋๋ค.
- ๋ค๋ฅธ ํ์
์ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
, I/O ์คํผ๋ ์ด์
์ ๋ํ ์์๋ ์์ ํ๊ฒ
- ๋ณด์ฅ๋์ง๋ ์์ต๋๋ค.
- (*) readX(), writeX():
- ์ด๊ฒ๋ค์ด ์ํ ์์ฒญ๋๋ CPU ์์ ์๋ก์๊ฒ ์์ ํ ์์๊ฐ ๋ง์ถฐ์ง๊ณ ๋
๋ฆฝ์ ์ผ๋ก
- ์ํ๋๋์ง์ ๋ํ ๋ณด์ฅ ์ฌ๋ถ๋ ์ด๋ค์ด ์ก์ธ์ค ํ๋ ๋ฉ๋ชจ๋ฆฌ ์๋์ฐ์ ์ ์๋
- ํน์ฑ์ ์ํด ๊ฒฐ์ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ต์ ์ i386 ์ํคํ
์ณ ๋จธ์ ์์๋ MTRR
- ๋ ์ง์คํฐ๋ก ์ด ํน์ฑ์ด ์กฐ์ ๋ฉ๋๋ค.
- ์ผ๋ฐ์ ์ผ๋ก๋, ํ๋ฆฌํ์น (prefetch) ๊ฐ๋ฅํ ๋๋ฐ์ด์ค๋ฅผ ์ก์ธ์ค ํ๋๊ฒ
- ์๋๋ผ๋ฉด, ์ด๊ฒ๋ค์ ์์ ํ ์์๊ฐ ๋ง์ถฐ์ง๊ณ ๊ฒฐํฉ๋์ง ์๊ฒ ๋ณด์ฅ๋ ๊ฒ๋๋ค.
- ํ์ง๋ง, (PCI ๋ธ๋ฆฌ์ง์ ๊ฐ์) ์ค๊ฐ์ ํ๋์จ์ด๋ ์์ ์ด ์ํ๋ค๋ฉด ์งํ์
- ์ฐ๊ธฐ์ํฌ ์ ์์ต๋๋ค; ์คํ ์ด ๋ช
๋ น์ ์ค์ ๋ก ํ๋์จ์ด๋ก ๋ด๋ ค๋ณด๋ด๊ธฐ(flush)
- ์ํด์๋ ๊ฐ์ ์์น๋ก๋ถํฐ ๋ก๋๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค๋ง[*], PCI ์ ๊ฒฝ์ฐ๋
- ๊ฐ์ ๋๋ฐ์ด์ค๋ ํ๊ฒฝ ๊ตฌ์ฑ ์์ญ์์์ ๋ก๋๋ง์ผ๋ก๋ ์ถฉ๋ถํ ๊ฒ๋๋ค.
- [*] ์ฃผ์! ์ฐ์ฌ์ง ๊ฒ๊ณผ ๊ฐ์ ์์น๋ก๋ถํฐ์ ๋ก๋๋ฅผ ์๋ํ๋ ๊ฒ์ ์ค๋์์
- ์ผ์ผํฌ ์๋ ์์ต๋๋ค - ์๋ก 16650 Rx/Tx ์๋ฆฌ์ผ ๋ ์ง์คํฐ๋ฅผ ์๊ฐํด
- ๋ณด์ธ์.
- ํ๋ฆฌํ์น ๊ฐ๋ฅํ I/O ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฌ์ฉ๋๋ฉด, ์คํ ์ด ๋ช
๋ น๋ค์ด ์์๋ฅผ ์งํค๋๋ก
- ํ๊ธฐ ์ํด mmiowb() ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์ํ ์ ์์ต๋๋ค.
- PCI ํธ๋์ญ์
์ฌ์ด์ ์ํธ์์ฉ์ ๋ํด ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ PCI ๋ช
์ธ์๋ฅผ
- ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
- (*) readX_relaxed(), writeX_relaxed()
- ์ด๊ฒ๋ค์ readX() ์ writeX() ๋ ๋น์ทํ์ง๋ง, ๋ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์์ ๋ณด์ฅ์
- ์ ๊ณตํฉ๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก, ์ด๊ฒ๋ค์ ์ผ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค (์: DMA ๋ฒํผ) ์๋
- LOCK ์ด๋ UNLOCK ์คํผ๋ ์ด์
๋ค์๋ ์์๋ฅผ ๋ณด์ฅํ์ง ์์ต๋๋ค. LOCK ์ด๋
- UNLOCK ์คํผ๋ ์ด์
๋ค์ ๋ง์ถฐ์ง๋ ์์๊ฐ ํ์ํ๋ค๋ฉด, mmiowb() ๋ฐฐ๋ฆฌ์ด๊ฐ ์ฌ์ฉ๋
- ์ ์์ต๋๋ค. ๊ฐ์ ์ฃผ๋ณ ์ฅ์น์์ ์ํ๋ ์ก์ธ์ค๋ผ๋ฆฌ๋ ์์๊ฐ ์ง์ผ์ง์ ์์
- ๋์๊ธฐ ๋ฐ๋๋๋ค.
- (*) ioreadX(), iowriteX()
- ์ด๊ฒ๋ค์ inX()/outX() ๋ readX()/writeX() ์ฒ๋ผ ์ค์ ๋ก ์ํํ๋ ์ก์ธ์ค์
- ์ข
๋ฅ์ ๋ฐ๋ผ ์ ์ ํ๊ฒ ์ํ๋ ๊ฒ์
๋๋ค.
- ===================================
- ๊ฐ์ ๋๋ ๊ฐ์ฅ ์ํ๋ ์คํ ์์ ๋ชจ๋ธ
- ===================================
- ์ปจ์
์ ์ผ๋ก CPU ๋ ์ฃผ์ด์ง ํ๋ก๊ทธ๋จ์ ๋ํด ํ๋ก๊ทธ๋จ ๊ทธ ์์ฒด์๋ ์ธ๊ณผ์ฑ (program
- causality) ์ ์งํค๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก๋ ์์๋ฅผ ๊ฑฐ์ ์ง์ผ์ฃผ์ง
- ์๋๋ค๊ณ ๊ฐ์ ๋์ด์ผ๋ง ํฉ๋๋ค. (i386 ์ด๋ x86_64 ๊ฐ์) ์ผ๋ถ CPU ๋ค์ ์ฝ๋
- ์ฌ๋ฐฐ์น์ (powerpc ๋ frv ์ ๊ฐ์) ๋ค๋ฅธ ๊ฒ๋ค์ ๋นํด ๊ฐํ ์ ์ฝ์ ๊ฐ์ง๋ง, ์ํคํ
์ณ
- ์ข
์์ ์ฝ๋ ์ด์ธ์ ์ฝ๋์์๋ ์์์ ๋ํ ์ ์ฝ์ด ๊ฐ์ฅ ์ํ๋ ๊ฒฝ์ฐ (DEC Alpha)
- ๋ฅผ ๊ฐ์ ํด์ผ ํฉ๋๋ค.
- ์ด ๋ง์, CPU ์๊ฒ ์ฃผ์ด์ง๋ ์ธ์คํธ๋ญ์
์คํธ๋ฆผ ๋ด์ ํ ์ธ์คํธ๋ญ์
์ด ์์
- ์ธ์คํธ๋ญ์
์ ์ข
์์ ์ด๋ผ๋ฉด ์์ ์ธ์คํธ๋ญ์
์ ๋ค์ ์ข
์์ ์ธ์คํธ๋ญ์
์ด ์คํ๋๊ธฐ
- ์ ์ ์๋ฃ[*]๋ ์ ์์ด์ผ ํ๋ค๋ ์ ์ฝ (๋ฌ๋ฆฌ ๋งํด์, ์ธ๊ณผ์ฑ์ด ์ง์ผ์ง๋ ๊ฒ์ผ๋ก
- ๋ณด์ด๊ฒ ํจ) ์ธ์๋ ์์ ์ด ์ํ๋ ์์๋๋ก - ์ฌ์ง์ด ๋ณ๋ ฌ์ ์ผ๋ก๋ - ๊ทธ ์คํธ๋ฆผ์
- ์คํํ ์ ์์์ ์๋ฏธํฉ๋๋ค
- [*] ์ผ๋ถ ์ธ์คํธ๋ญ์
์ ํ๋ ์ด์์ ์ํฅ - ์กฐ๊ฑด ์ฝ๋๋ฅผ ๋ฐ๊พผ๋ค๋์ง, ๋ ์ง์คํฐ๋
- ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ๊พผ๋ค๋์ง - ์ ๋ง๋ค์ด๋ด๋ฉฐ, ๋ค๋ฅธ ์ธ์คํธ๋ญ์
์ ๋ค๋ฅธ ํจ๊ณผ์
- ์ข
์์ ์ผ ์ ์์ต๋๋ค.
- CPU ๋ ์ต์ข
์ ์ผ๋ก ์๋ฌด ํจ๊ณผ๋ ๋ง๋ค์ง ์๋ ์ธ์คํธ๋ญ์
์ํ์ค๋ ์์ ๋ฒ๋ฆด ์๋
- ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ง์ฝ ๋๊ฐ์ ์ฐ์๋๋ ์ธ์คํธ๋ญ์
์ด ๋ ๋ค ๊ฐ์ ๋ ์ง์คํฐ์
- ์ง์ ์ ์ธ ๊ฐ (immediate value) ์ ์ง์ด๋ฃ๋๋ค๋ฉด, ์ฒซ๋ฒ์งธ ์ธ์คํธ๋ญ์
์ ๋ฒ๋ ค์ง ์๋
- ์์ต๋๋ค.
- ๋น์ทํ๊ฒ, ์ปดํ์ผ๋ฌ ์ญ์ ํ๋ก๊ทธ๋จ์ ์ธ๊ณผ์ฑ๋ง ์ง์ผ์ค๋ค๋ฉด ์ธ์คํธ๋ญ์
์คํธ๋ฆผ์
- ์์ ์ด ๋ณด๊ธฐ์ ์ฌ๋ฐ๋ฅด๋ค ์๊ฐ๋๋๋๋ก ์ฌ๋ฐฐ์น ํ ์ ์์ต๋๋ค.
- ===============
- CPU ์บ์์ ์ํฅ
- ===============
- ์บ์๋ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ด ์์คํ
์ ์ฒด์ ์ด๋ป๊ฒ ์ธ์ง๋๋์ง๋ CPU ์ ๋ฉ๋ชจ๋ฆฌ
- ์ฌ์ด์ ์กด์ฌํ๋ ์บ์๋ค, ๊ทธ๋ฆฌ๊ณ ์์คํ
์ํ์ ์ผ๊ด์ฑ์ ๊ด๋ฆฌํ๋ ๋ฉ๋ชจ๋ฆฌ ์ผ๊ด์ฑ
- ์์คํ
์ ์๋น ๋ถ๋ถ ์ํฅ์ ๋ฐ์ต๋๋ค.
- ํ CPU ๊ฐ ์์คํ
์ ๋ค๋ฅธ ๋ถ๋ถ๋ค๊ณผ ์บ์๋ฅผ ํตํด ์ํธ์์ฉํ๋ค๋ฉด, ๋ฉ๋ชจ๋ฆฌ ์์คํ
์
- CPU ์ ์บ์๋ค์ ํฌํจํด์ผ ํ๋ฉฐ, CPU ์ CPU ์์ ์ ์บ์ ์ฌ์ด์์์ ๋์์ ์ํ
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๊ฐ์ ธ์ผ ํฉ๋๋ค. (๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ๋
ผ๋ฆฌ์ ์ผ๋ก๋ ๋ค์ ๊ทธ๋ฆผ์
- ์ ์ ์์ ๋์ํฉ๋๋ค):
- <--- CPU ---> : <----------- Memory ----------->
- :
- +--------+ +--------+ : +--------+ +-----------+
- | | | | : | | | | +--------+
- | CPU | | Memory | : | CPU | | | | |
- | Core |--->| Access |----->| Cache |<-->| | | |
- | | | Queue | : | | | |--->| Memory |
- | | | | : | | | | | |
- +--------+ +--------+ : +--------+ | | | |
- : | Cache | +--------+
- : | Coherency |
- : | Mechanism | +--------+
- +--------+ +--------+ : +--------+ | | | |
- | | | | : | | | | | |
- | CPU | | Memory | : | CPU | | |--->| Device |
- | Core |--->| Access |----->| Cache |<-->| | | |
- | | | Queue | : | | | | | |
- | | | | : | | | | +--------+
- +--------+ +--------+ : +--------+ +-----------+
- :
- :
- ํน์ ๋ก๋๋ ์คํ ์ด๋ ํด๋น ์คํผ๋ ์ด์
์ ์์ฒญํ CPU ์ ์บ์ ๋ด์์ ๋์์ ์๋ฃํ
- ์๋ ์๊ธฐ ๋๋ฌธ์ ํด๋น CPU ์ ๋ฐ๊นฅ์๋ ๋ณด์ด์ง ์์ ์ ์์ง๋ง, ๋ค๋ฅธ CPU ๊ฐ ๊ด์ฌ์
- ๊ฐ๋๋ค๋ฉด ์บ์ ์ผ๊ด์ฑ ๋ฉ์ปค๋์ฆ์ด ํด๋น ์บ์๋ผ์ธ์ ํด๋น CPU ์๊ฒ ์ ๋ฌํ๊ณ , ํด๋น
- ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ํ ์คํผ๋ ์ด์
์ด ๋ฐ์ํ ๋๋ง๋ค ๊ทธ ์ํฅ์ ์ ํ์ํค๊ธฐ ๋๋ฌธ์, ํด๋น
- ์คํผ๋ ์ด์
์ ๋ฉ๋ชจ๋ฆฌ์ ์ค์ ๋ก ์ก์ธ์ค๋ฅผ ํ๊ฒ์ฒ๋ผ ๋ํ๋ ๊ฒ์
๋๋ค.
- CPU ์ฝ์ด๋ ํ๋ก๊ทธ๋จ์ ์ธ๊ณผ์ฑ์ด ์ ์ง๋๋ค๊ณ ๋ง ์ฌ๊ฒจ์ง๋ค๋ฉด ์ธ์คํธ๋ญ์
๋ค์ ์ด๋ค
- ์์๋ก๋ ์ฌ๋ฐฐ์นํด์ ์ํํ ์ ์์ต๋๋ค. ์ผ๋ถ ์ธ์คํธ๋ญ์
๋ค์ ๋ก๋๋ ์คํ ์ด
- ์คํผ๋ ์ด์
์ ๋ง๋๋๋ฐ ์ด ์คํผ๋ ์ด์
๋ค์ ์ดํ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ํ์ ๋ค์ด๊ฐ๊ฒ
- ๋ฉ๋๋ค. ์ฝ์ด๋ ์ด ์คํผ๋ ์ด์
๋ค์ ํด๋น ํ์ ์ด๋ค ์์๋ก๋ ์ํ๋๋๋ก ๋ฃ์ ์
- ์๊ณ , ๋ค๋ฅธ ์ธ์คํธ๋ญ์
์ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋๋ก ๊ฐ์ ๋๊ธฐ ์ ๊น์ง๋ ์ํ์ ๊ณ์ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ๋ ์ผ์ CPU ์ชฝ์์ ๋ฉ๋ชจ๋ฆฌ ์ชฝ์ผ๋ก ๋์ด๊ฐ๋ ์ก์ธ์ค๋ค์ ์์,
- ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ก์ธ์ค์ ๊ฒฐ๊ณผ๊ฐ ์์คํ
์ ๋ค๋ฅธ ๊ด์ฐฐ์๋ค์๊ฒ ์ธ์ง๋๋ ์์๋ฅผ ์ ์ดํ๋
- ๊ฒ์
๋๋ค.
- [!] CPU ๋ค์ ํญ์ ๊ทธ๋ค ์์ ์ ๋ก๋์ ์คํ ์ด๋ ํ๋ก๊ทธ๋จ ์์๋๋ก ์ผ์ด๋ ๊ฒ์ผ๋ก
- ๋ณด๊ธฐ ๋๋ฌธ์, ์ฃผ์ด์ง CPU ๋ด์์๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ ํ์๊ฐ _์์ต๋๋ค_.
- [!] MMIO ๋ ๋ค๋ฅธ ๋๋ฐ์ด์ค ์ก์ธ์ค๋ค์ ์บ์ ์์คํ
์ ์ฐํํ ์๋ ์์ต๋๋ค. ์ฐํ
- ์ฌ๋ถ๋ ๋๋ฐ์ด์ค๊ฐ ์ก์ธ์ค ๋๋ ๋ฉ๋ชจ๋ฆฌ ์๋์ฐ์ ํน์ฑ์ ์ํด ๊ฒฐ์ ๋ ์๋ ์๊ณ , CPU
- ๊ฐ ๊ฐ์ง๊ณ ์์ ์ ์๋ ํน์ํ ๋๋ฐ์ด์ค ํต์ ์ธ์คํธ๋ญ์
์ ์ฌ์ฉ์ ์ํด์ ๊ฒฐ์ ๋
- ์๋ ์์ต๋๋ค.
- ์บ์ ์ผ๊ด์ฑ
- -----------
- ํ์ง๋ง ์ถ์ ์์์ ์ด์ผ๊ธฐํ ๊ฒ์ฒ๋ผ ๋จ์ํ์ง ์์ต๋๋ค: ์บ์๋ค์ ์ผ๊ด์ ์ผ ๊ฒ์ผ๋ก
- ๊ธฐ๋๋์ง๋ง, ๊ทธ ์ผ๊ด์ฑ์ด ์์์๋ ์ ์ฉ๋ ๊ฑฐ๋ผ๋ ๋ณด์ฅ์ ์์ต๋๋ค. ํ CPU ์์
- ๋ง๋ค์ด์ง ๋ณ๊ฒฝ ์ฌํญ์ ์ต์ข
์ ์ผ๋ก๋ ์์คํ
์ ๋ชจ๋ CPU ์๊ฒ ๋ณด์ฌ์ง๊ฒ ๋์ง๋ง, ๋ค๋ฅธ
- CPU ๋ค์๊ฒ๋ ๊ฐ์ ์์๋ก ๋ณด์ด๊ฒ ๋ ๊ฑฐ๋ผ๋ ๋ณด์ฅ์ ์๋ค๋ ๋ป์
๋๋ค.
- ๋๊ฐ์ CPU (1 & 2) ๊ฐ ๋ฌ๋ ค ์๊ณ , ๊ฐ CPU ์ ๋๊ฐ์ ๋ฐ์ดํฐ ์บ์(CPU 1 ์ A/B ๋ฅผ,
- CPU 2 ๋ C/D ๋ฅผ ๊ฐ์ต๋๋ค)๊ฐ ๋ณ๋ ฌ๋ก ์ฐ๊ฒฐ๋์ด ์๋ ์์คํ
์ ๋ค๋ฃฌ๋ค๊ณ ์๊ฐํด
- ๋ด
์๋ค:
- :
- : +--------+
- : +---------+ | |
- +--------+ : +--->| Cache A |<------->| |
- | | : | +---------+ | |
- | CPU 1 |<---+ | |
- | | : | +---------+ | |
- +--------+ : +--->| Cache B |<------->| |
- : +---------+ | |
- : | Memory |
- : +---------+ | System |
- +--------+ : +--->| Cache C |<------->| |
- | | : | +---------+ | |
- | CPU 2 |<---+ | |
- | | : | +---------+ | |
- +--------+ : +--->| Cache D |<------->| |
- : +---------+ | |
- : +--------+
- :
- ์ด ์์คํ
์ด ๋ค์๊ณผ ๊ฐ์ ํน์ฑ์ ๊ฐ๋๋ค ์๊ฐํด ๋ด
์๋ค:
- (*) ํ์๋ฒ ์บ์๋ผ์ธ์ ์บ์ A, ์บ์ C ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์์นํ ์ ์์;
- (*) ์ง์๋ฒ ์บ์๋ผ์ธ์ ์บ์ B, ์บ์ D ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์์นํ ์ ์์;
- (*) CPU ์ฝ์ด๊ฐ ํ๊ฐ์ ์บ์์ ์ ๊ทผํ๋ ๋์, ๋ค๋ฅธ ์บ์๋ - ๋ํฐ ์บ์๋ผ์ธ์
- ๋ฉ๋ชจ๋ฆฌ์ ๋ด๋ฆฌ๊ฑฐ๋ ์ถ์ธก์ฑ ๋ก๋๋ฅผ ํ๊ฑฐ๋ ํ๊ธฐ ์ํด - ์์คํ
์ ๋ค๋ฅธ ๋ถ๋ถ์
- ์ก์ธ์ค ํ๊ธฐ ์ํด ๋ฒ์ค๋ฅผ ์ฌ์ฉํ ์ ์์;
- (*) ๊ฐ ์บ์๋ ์์คํ
์ ๋๋จธ์ง ๋ถ๋ถ๋ค๊ณผ ์ผ๊ด์ฑ์ ๋ง์ถ๊ธฐ ์ํด ํด๋น ์บ์์
- ์ ์ฉ๋์ด์ผ ํ ์คํผ๋ ์ด์
๋ค์ ํ๋ฅผ ๊ฐ์ง;
- (*) ์ด ์ผ๊ด์ฑ ํ๋ ์บ์์ ์ด๋ฏธ ์กด์ฌํ๋ ๋ผ์ธ์ ๊ฐํด์ง๋ ํ๋ฒํ ๋ก๋์ ์ํด์๋
- ๋น์์ง์ง ์๋๋ฐ, ํ์ ์คํผ๋ ์ด์
๋ค์ด ์ด ๋ก๋์ ๊ฒฐ๊ณผ์ ์ํฅ์ ๋ผ์น ์ ์๋ค
- ํ ์ง๋ผ๋ ๊ทธ๋ฌํจ.
- ์ด์ , ์ฒซ๋ฒ์งธ CPU ์์ ๋๊ฐ์ ์ฐ๊ธฐ ์คํผ๋ ์ด์
์ ๋ง๋๋๋ฐ, ํด๋น CPU ์ ์บ์์
- ์์ฒญ๋ ์์๋ก ์คํผ๋ ์ด์
์ด ๋๋ฌ๋จ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ ์คํผ๋ ์ด์
์ฌ์ด์ ์ฐ๊ธฐ
- ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํ๋ ์ํฉ์ ์์ํด ๋ด
์๋ค:
- CPU 1 CPU 2 COMMENT
- =============== =============== =======================================
- u == 0, v == 1 and p == &u, q == &u
- v = 2;
- smp_wmb(); v ์ ๋ณ๊ฒฝ์ด p ์ ๋ณ๊ฒฝ ์ ์ ๋ณด์ผ ๊ฒ์
- ๋ถ๋ช
ํ ํจ
- <A:modify v=2> v ๋ ์ด์ ์บ์ A ์ ๋
์ ์ ์ผ๋ก ์กด์ฌํจ
- p = &v;
- <B:modify p=&v> p ๋ ์ด์ ์บ์ B ์ ๋
์ ์ ์ผ๋ก ์กด์ฌํจ
- ์ฌ๊ธฐ์์ ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ CPU 1 ์ ์บ์๊ฐ ์ฌ๋ฐ๋ฅธ ์์๋ก ์
๋ฐ์ดํธ ๋ ๊ฒ์ผ๋ก
- ์์คํ
์ ๋ค๋ฅธ CPU ๋ค์ด ์ธ์งํ๊ฒ ๋ง๋ญ๋๋ค. ํ์ง๋ง, ์ด์ ๋๋ฒ์งธ CPU ๊ฐ ๊ทธ ๊ฐ๋ค์
- ์ฝ์ผ๋ ค ํ๋ ์ํฉ์ ์๊ฐํด ๋ด
์๋ค:
- CPU 1 CPU 2 COMMENT
- =============== =============== =======================================
- ...
- q = p;
- x = *q;
- ์์ ๋๊ฐ์ ์ฝ๊ธฐ ์คํผ๋ ์ด์
์ ์์๋ ์์๋ก ์ผ์ด๋์ง ๋ชปํ ์ ์๋๋ฐ, ๋๋ฒ์งธ CPU
- ์ ํ ์บ์์ ๋ค๋ฅธ ์บ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํด v ๋ฅผ ๋ด๊ณ ์๋ ์บ์๋ผ์ธ์ ํด๋น ์บ์์์
- ์
๋ฐ์ดํธ๊ฐ ์ง์ฐ๋๋ ์ฌ์ด, p ๋ฅผ ๋ด๊ณ ์๋ ์บ์๋ผ์ธ์ ๋๋ฒ์งธ CPU ์ ๋ค๋ฅธ ์บ์์
- ์
๋ฐ์ดํธ ๋์ด๋ฒ๋ ธ์ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
- CPU 1 CPU 2 COMMENT
- =============== =============== =======================================
- u == 0, v == 1 and p == &u, q == &u
- v = 2;
- smp_wmb();
- <A:modify v=2> <C:busy>
- <C:queue v=2>
- p = &v; q = p;
- <D:request p>
- <B:modify p=&v> <D:commit p=&v>
- <D:read p>
- x = *q;
- <C:read *q> ์บ์์ ์
๋ฐ์ดํธ ๋๊ธฐ ์ ์ v ๋ฅผ ์ฝ์
- <C:unbusy>
- <C:commit v=2>
- ๊ธฐ๋ณธ์ ์ผ๋ก, ๋๊ฐ์ ์บ์๋ผ์ธ ๋ชจ๋ CPU 2 ์ ์ต์ข
์ ์ผ๋ก๋ ์
๋ฐ์ดํธ ๋ ๊ฒ์ด์ง๋ง,
- ๋ณ๋์ ๊ฐ์
์์ด๋, ์
๋ฐ์ดํธ์ ์์๊ฐ CPU 1 ์์ ๋ง๋ค์ด์ง ์์์ ๋์ผํ
- ๊ฒ์ด๋ผ๋ ๋ณด์ฅ์ด ์์ต๋๋ค.
- ์ฌ๊ธฐ์ ๊ฐ์
ํ๊ธฐ ์ํด์ , ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ ์ฝ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ก๋ ์คํผ๋ ์ด์
๋ค
- ์ฌ์ด์ ๋ฃ์ด์ผ ํฉ๋๋ค. ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ์บ์๊ฐ ๋ค์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ์ผ๊ด์ฑ
- ํ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๊ฐ์ ํ๊ฒ ๋ฉ๋๋ค.
- CPU 1 CPU 2 COMMENT
- =============== =============== =======================================
- u == 0, v == 1 and p == &u, q == &u
- v = 2;
- smp_wmb();
- <A:modify v=2> <C:busy>
- <C:queue v=2>
- p = &v; q = p;
- <D:request p>
- <B:modify p=&v> <D:commit p=&v>
- <D:read p>
- smp_read_barrier_depends()
- <C:unbusy>
- <C:commit v=2>
- x = *q;
- <C:read *q> ์บ์์ ์
๋ฐ์ดํธ ๋ v ๋ฅผ ์ฝ์
- ์ด๋ฐ ๋ถ๋ฅ์ ๋ฌธ์ ๋ DEC Alpha ๊ณ์ด ํ๋ก์ธ์๋ค์์ ๋ฐ๊ฒฌ๋ ์ ์๋๋ฐ, ์ด๋ค์
- ๋ฐ์ดํฐ ๋ฒ์ค๋ฅผ ์ข ๋ ์ ์ฌ์ฉํด ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์๋, ๋ถํ ๋ ์บ์๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ
- ๋๋ฌธ์
๋๋ค. ๋๋ถ๋ถ์ CPU ๋ ํ๋์ ์ฝ๊ธฐ ์คํผ๋ ์ด์
์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๊ฐ ๋ค๋ฅธ ์ฝ๊ธฐ
- ์คํผ๋ ์ด์
์ ์์กด์ ์ด๋ผ๋ฉด ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋ฅผ ๋ดํฌ์ํต๋๋ค๋ง, ๋ชจ๋๊ฐ ๊ทธ๋ฐ๊ฑด
- ์๋๊ธฐ ๋๋ฌธ์ ์ด์ ์ ์์กดํด์ ์๋ฉ๋๋ค.
- ๋ค๋ฅธ CPU ๋ค๋ ๋ถํ ๋ ์บ์๋ฅผ ๊ฐ์ง๊ณ ์์ ์ ์์ง๋ง, ๊ทธ๋ฐ CPU ๋ค์ ํ๋ฒํ ๋ฉ๋ชจ๋ฆฌ
- ์ก์ธ์ค๋ฅผ ์ํด์๋ ์ด ๋ถํ ๋ ์บ์๋ค ์ฌ์ด์ ์กฐ์ ์ ํด์ผ๋ง ํฉ๋๋ค. Alpha ๋ ๊ฐ์ฅ
- ์ฝํ ๋ฉ๋ชจ๋ฆฌ ์์ ์๋งจํฑ (semantic) ์ ์ ํํจ์ผ๋ก์จ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ๋ช
์์ ์ผ๋ก
- ์ฌ์ฉ๋์ง ์์์ ๋์๋ ๊ทธ๋ฐ ์กฐ์ ์ด ํ์ํ์ง ์๊ฒ ํ์ต๋๋ค.
- ์บ์ ์ผ๊ด์ฑ VS DMA
- ------------------
- ๋ชจ๋ ์์คํ
์ด DMA ๋ฅผ ํ๋ ๋๋ฐ์ด์ค์ ๋ํด์๊น์ง ์บ์ ์ผ๊ด์ฑ์ ์ ์งํ์ง๋
- ์์ต๋๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ, DMA ๋ฅผ ์๋ํ๋ ๋๋ฐ์ด์ค๋ RAM ์ผ๋ก๋ถํฐ ์๋ชป๋ ๋ฐ์ดํฐ๋ฅผ
- ์ฝ์ ์ ์๋๋ฐ, ๋ํฐ ์บ์ ๋ผ์ธ์ด CPU ์ ์บ์์ ๋จธ๋ฌด๋ฅด๊ณ ์๊ณ , ๋ฐ๋ ๊ฐ์ด ์์ง
- RAM ์ ์จ์ง์ง ์์์ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ , ์ปค๋์
- ์ ์ ํ ๋ถ๋ถ์์ ๊ฐ CPU ์บ์์ ๋ฌธ์ ๋๋ ๋นํธ๋ค์ ํ๋ฌ์ (flush) ์์ผ์ผ๋ง ํฉ๋๋ค
- (๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ๋ค์ ๋ฌดํจํ - invalidation - ์ํฌ ์๋ ์๊ฒ ์ฃ ).
- ๋ํ, ๋๋ฐ์ด์ค์ ์ํด RAM ์ DMA ๋ก ์ฐ์ฌ์ง ๊ฐ์ ๋๋ฐ์ด์ค๊ฐ ์ฐ๊ธฐ๋ฅผ ์๋ฃํ ํ์
- CPU ์ ์บ์์์ RAM ์ผ๋ก ์ฐ์ฌ์ง๋ ๋ํฐ ์บ์ ๋ผ์ธ์ ์ํด ๋ฎ์ด์จ์ง ์๋ ์๊ณ , CPU
- ์ ์บ์์ ์กด์ฌํ๋ ์บ์ ๋ผ์ธ์ด ํด๋น ์บ์์์ ์ญ์ ๋๊ณ ๋ค์ ๊ฐ์ ์ฝ์ด๋ค์ด๊ธฐ
- ์ ๊น์ง๋ RAM ์ด ์
๋ฐ์ดํธ ๋์๋ค๋ ์ฌ์ค ์์ฒด๊ฐ ์จ๊ฒจ์ ธ ๋ฒ๋ฆด ์๋ ์์ต๋๋ค. ์ด
- ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ , ์ปค๋์ ์ ์ ํ ๋ถ๋ถ์์ ๊ฐ CPU ์ ์บ์ ์์ ๋ฌธ์ ๊ฐ ๋๋
- ๋นํธ๋ค์ ๋ฌดํจํ ์์ผ์ผ ํฉ๋๋ค.
- ์บ์ ๊ด๋ฆฌ์ ๋ํ ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํด์ Documentation/cachetlb.txt ๋ฅผ
- ์ฐธ๊ณ ํ์ธ์.
- ์บ์ ์ผ๊ด์ฑ VS MMIO
- -------------------
- Memory mapped I/O ๋ ์ผ๋ฐ์ ์ผ๋ก CPU ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ๋ด์ ํ ์๋์ฐ์ ํน์ ๋ถ๋ถ
- ๋ด์ ๋ฉ๋ชจ๋ฆฌ ์ง์ญ์ ์ด๋ฃจ์ด์ง๋๋ฐ, ์ด ์๋์ฐ๋ ์ผ๋ฐ์ ์ธ, RAM ์ผ๋ก ํฅํ๋
- ์๋์ฐ์๋ ๋ค๋ฅธ ํน์ฑ์ ๊ฐ์ต๋๋ค.
- ๊ทธ๋ฐ ํน์ฑ ๊ฐ์ด๋ฐ ํ๋๋, ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ฐ ์ก์ธ์ค๋ ์บ์๋ฅผ ์์ ํ ์ฐํํ๊ณ
- ๋๋ฐ์ด์ค ๋ฒ์ค๋ก ๊ณง๋ฐ๋ก ํฅํ๋ค๋ ๊ฒ์
๋๋ค. ์ด ๋ง์ MMIO ์ก์ธ์ค๋ ๋จผ์
- ์์๋์ด์ ์บ์์์ ์๋ฃ๋ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค๋ฅผ ์ถ์ํ ์ ์๋ค๋ ๋ป์
๋๋ค. ์ด๋ฐ
- ๊ฒฝ์ฐ์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ง์ผ๋ก๋ ์ถฉ๋ถ์น ์๊ณ , ๋ง์ฝ ์บ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ ์คํผ๋ ์ด์
๊ณผ
- MMIO ์ก์ธ์ค๊ฐ ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ์์กด์ ์ด๋ผ๋ฉด ํด๋น ์บ์๋ ๋ ์คํผ๋ ์ด์
์ฌ์ด์
- ๋น์์ ธ(flush)์ผ๋ง ํฉ๋๋ค.
- ======================
- CPU ๋ค์ด ์ ์ง๋ฅด๋ ์ผ๋ค
- ======================
- ํ๋ก๊ทธ๋๋จธ๋ CPU ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์คํผ๋ ์ด์
๋ค์ ์ ํํ ์์ฒญํ๋๋ก ์ํํด ์ค ๊ฒ์ด๋ผ๊ณ
- ์๊ฐํ๋๋ฐ, ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ CPU ์๊ฒ ๋๊ธด๋ค๋ฉด:
- a = READ_ONCE(*A);
- WRITE_ONCE(*B, b);
- c = READ_ONCE(*C);
- d = READ_ONCE(*D);
- WRITE_ONCE(*E, e);
- CPU ๋ ๋ค์ ์ธ์คํธ๋ญ์
์ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ํ์ฌ์ ์ธ์คํธ๋ญ์
์ ์ํ ๋ฉ๋ชจ๋ฆฌ
- ์คํผ๋ ์ด์
์ ์๋ฃํ ๊ฒ์ด๋ผ ์๊ฐํ๊ณ , ๋ฐ๋ผ์ ์์คํ
์ธ๋ถ์์ ๊ด์ฐฐํ๊ธฐ์๋ ์ ํด์ง
- ์์๋๋ก ์คํผ๋ ์ด์
์ด ์ํ๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค:
- LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E.
- ๋น์ฐํ์ง๋ง, ์ค์ ๋ก๋ ํจ์ฌ ์๋ง์
๋๋ค. ๋ง์ CPU ์ ์ปดํ์ผ๋ฌ์์ ์์ ๊ฐ์ ์
- ์ฑ๋ฆฝํ์ง ๋ชปํ๋๋ฐ ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- (*) ๋ก๋ ์คํผ๋ ์ด์
๋ค์ ์คํ์ ๊ณ์ ํด๋๊ฐ๊ธฐ ์ํด ๊ณง๋ฐ๋ก ์๋ฃ๋ ํ์๊ฐ ์๋
- ๊ฒฝ์ฐ๊ฐ ๋ง์ ๋ฐ๋ฉด, ์คํ ์ด ์คํผ๋ ์ด์
๋ค์ ์ข
์ข
๋ณ๋ค๋ฅธ ๋ฌธ์ ์์ด ์ ์๋ ์
- ์์ต๋๋ค;
- (*) ๋ก๋ ์คํผ๋ ์ด์
๋ค์ ์์ธก์ ์ผ๋ก ์ํ๋ ์ ์์ผ๋ฉฐ, ํ์์๋ ๋ก๋์๋ค๊ณ
- ์ฆ๋ช
๋ ์์ธก์ ๋ก๋์ ๊ฒฐ๊ณผ๋ ๋ฒ๋ ค์ง๋๋ค;
- (*) ๋ก๋ ์คํผ๋ ์ด์
๋ค์ ์์ธก์ ์ผ๋ก ์ํ๋ ์ ์์ผ๋ฏ๋ก, ์์๋ ์ด๋ฒคํธ์
- ์ํ์ค์ ๋ค๋ฅธ ์๊ฐ์ ๋ก๋๊ฐ ์ด๋ค์ง ์ ์์ต๋๋ค;
- (*) ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ์์๋ CPU ๋ฒ์ค์ ์บ์๋ฅผ ์ข ๋ ์ ์ฌ์ฉํ ์ ์๋๋ก ์ฌ๋ฐฐ์น
- ๋ ์ ์์ต๋๋ค;
- (*) ๋ก๋์ ์คํ ์ด๋ ์ธ์ ํ ์์น์์ ์ก์ธ์ค๋ค์ ์ผ๊ด์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋
- ๋ฉ๋ชจ๋ฆฌ๋ I/O ํ๋์จ์ด (๋ฉ๋ชจ๋ฆฌ์ PCI ๋๋ฐ์ด์ค ๋ ๋ค ์ด๊ฒ ๊ฐ๋ฅํ ์
- ์์ต๋๋ค) ์ ๋ํด ์์ฒญ๋๋ ๊ฒฝ์ฐ, ๊ฐ๋ณ ์คํผ๋ ์ด์
์ ์ํ ํธ๋์ญ์
์ค์
- ๋น์ฉ์ ์๋ผ๊ธฐ ์ํด ์กฐํฉ๋์ด ์คํ๋ ์ ์์ต๋๋ค; ๊ทธ๋ฆฌ๊ณ
- (*) ํด๋น CPU ์ ๋ฐ์ดํฐ ์บ์๊ฐ ์์์ ์ํฅ์ ๋ผ์น ์๋ ์๊ณ , ์บ์ ์ผ๊ด์ฑ
- ๋ฉ์ปค๋์ฆ์ด - ์คํ ์ด๊ฐ ์ค์ ๋ก ์บ์์ ๋๋ฌํ๋ค๋ฉด - ์ด ๋ฌธ์ ๋ฅผ ์ํ์ํฌ ์๋
- ์์ง๋ง ์ด ์ผ๊ด์ฑ ๊ด๋ฆฌ๊ฐ ๋ค๋ฅธ CPU ๋ค์๋ ๊ฐ์ ์์๋ก ์ ๋ฌ๋๋ค๋ ๋ณด์ฅ์
- ์์ต๋๋ค.
- ๋ฐ๋ผ์, ์์ ์ฝ๋์ ๋ํด ๋ค๋ฅธ CPU ๊ฐ ๋ณด๋ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
- LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B
- ("LOAD {*C,*D}" ๋ ์กฐํฉ๋ ๋ก๋์
๋๋ค)
- ํ์ง๋ง, CPU ๋ ์ค์ค๋ก๋ ์ผ๊ด์ ์ผ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค: CPU _์์ _ ์ ์ก์ธ์ค๋ค์
- ์์ ์๊ฒ๋ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๊ฐ ์์์๋ ๋ถ๊ตฌํ๊ณ ์ ํํ ์์ ์ธ์์ง ๊ฒ์ผ๋ก ๋ณด์ฌ์ง
- ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์์ ์ฝ๋๊ฐ ์ฃผ์ด์ก๋ค๋ฉด:
- U = READ_ONCE(*A);
- WRITE_ONCE(*A, V);
- WRITE_ONCE(*A, W);
- X = READ_ONCE(*A);
- WRITE_ONCE(*A, Y);
- Z = READ_ONCE(*A);
- ๊ทธ๋ฆฌ๊ณ ์ธ๋ถ์ ์ํฅ์ ์ํ ๊ฐ์ญ์ด ์๋ค๊ณ ๊ฐ์ ํ๋ฉด, ์ต์ข
๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ด
- ๋ํ๋ ๊ฒ์ด๋ผ๊ณ ์์๋ ์ ์์ต๋๋ค:
- U == *A ์ ์ต์ด ๊ฐ
- X == W
- Z == Y
- *A == Y
- ์์ ์ฝ๋๋ CPU ๊ฐ ๋ค์์ ๋ฉ๋ชจ๋ฆฌ ์ก์ธ์ค ์ํ์ค๋ฅผ ๋ง๋ค๋๋ก ํ ๊ฒ๋๋ค:
- U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A
- ํ์ง๋ง, ๋ณ๋ค๋ฅธ ๊ฐ์
์ด ์๊ณ ํ๋ก๊ทธ๋จ์ ์์ผ์ ์ด ์ธ์์ด ์ฌ์ ํ ์ผ๊ด์ ์ด๋ผ๊ณ
- ๋ณด์ธ๋ค๋ ๋ณด์ฅ๋ง ์ง์ผ์ง๋ค๋ฉด ์ด ์ํ์ค๋ ์ด๋ค ์กฐํฉ์ผ๋ก๋ ์ฌ๊ตฌ์ฑ๋ ์ ์์ผ๋ฉฐ, ๊ฐ
- ์ก์ธ์ค๋ค์ ํฉ์ณ์ง๊ฑฐ๋ ๋ฒ๋ ค์ง ์ ์์ต๋๋ค. ์ผ๋ถ ์ํคํ
์ณ์์ CPU ๋ ๊ฐ์ ์์น์
- ๋ํ ์ฐ์์ ์ธ ๋ก๋ ์คํผ๋ ์ด์
๋ค์ ์ฌ๋ฐฐ์น ํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ ์์์์
- READ_ONCE() ์ WRITE_ONCE() ๋ ๋ฐ๋์ ์กด์ฌํด์ผ ํจ์ ์์๋์ธ์. ๊ทธ๋ฐ ์ข
๋ฅ์
- ์ํคํ
์ณ์์ READ_ONCE() ์ WRITE_ONCE() ๋ ์ด ๋ฌธ์ ๋ฅผ ๋ง๊ธฐ ์ํด ํ์ํ ์ผ์
- ๋ญ๊ฐ ๋๋ ์ง ํ๊ฒ ๋๋๋ฐ, ์๋ฅผ ๋ค์ด Itanium ์์๋ READ_ONCE() ์ WRITE_ONCE()
- ๊ฐ ์ฌ์ฉํ๋ volatile ์บ์คํ
์ GCC ๊ฐ ๊ทธ๋ฐ ์ฌ๋ฐฐ์น๋ฅผ ๋ฐฉ์งํ๋ ํน์ ์ธ์คํธ๋ญ์
์ธ
- ld.acq ์ stl.rel ์ธ์คํธ๋ญ์
์ ๊ฐ๊ฐ ๋ง๋ค์ด ๋ด๋๋ก ํฉ๋๋ค.
- ์ปดํ์ผ๋ฌ ์ญ์ ์ด ์ํ์ค์ ์ก์ธ์ค๋ค์ CPU ๊ฐ ๋ณด๊ธฐ๋ ์ ์ ํฉ์น๊ฑฐ๋ ๋ฒ๋ฆฌ๊ฑฐ๋ ๋ค๋ก
- ๋ฏธ๋ค๋ฒ๋ฆด ์ ์์ต๋๋ค.
- ์๋ฅผ ๋ค์ด:
- *A = V;
- *A = W;
- ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณํ๋ ์ ์์ต๋๋ค:
- *A = W;
- ๋ฐ๋ผ์, ์ฐ๊ธฐ ๋ฐฐ๋ฆฌ์ด๋ WRITE_ONCE() ๊ฐ ์๋ค๋ฉด *A ๋ก์ V ๊ฐ์ ์ ์ฅ์ ํจ๊ณผ๋
- ์ฌ๋ผ์ง๋ค๊ณ ๊ฐ์ ๋ ์ ์์ต๋๋ค. ๋น์ทํ๊ฒ:
- *A = Y;
- Z = *A;
- ๋, ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ READ_ONCE() ์ WRITE_ONCE() ์์ด๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณํ๋ ์
- ์์ต๋๋ค:
- *A = Y;
- Z = Y;
- ๊ทธ๋ฆฌ๊ณ ์ด LOAD ์คํผ๋ ์ด์
์ CPU ๋ฐ๊นฅ์๋ ์์ ๋ณด์ด์ง ์์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ , ALPHA ๊ฐ ์๋ค
- ---------------------
- DEC Alpha CPU ๋ ๊ฐ์ฅ ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์์์ CPU ์ค ํ๋์
๋๋ค. ๋ฟ๋ง ์๋๋ผ,
- Alpha CPU ์ ์ผ๋ถ ๋ฒ์ ์ ๋ถํ ๋ ๋ฐ์ดํฐ ์บ์๋ฅผ ๊ฐ์ง๊ณ ์์ด์, ์๋ฏธ์ ์ผ๋ก
- ๊ด๊ณ๋์ด ์๋ ๋๊ฐ์ ์บ์ ๋ผ์ธ์ด ์๋ก ๋ค๋ฅธ ์๊ฐ์ ์
๋ฐ์ดํธ ๋๋๊ฒ ๊ฐ๋ฅํฉ๋๋ค.
- ์ด๊ฒ ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๊ฐ ์ ๋ง ํ์ํด์ง๋ ๋ถ๋ถ์ธ๋ฐ, ๋ฐ์ดํฐ ์์กด์ฑ ๋ฐฐ๋ฆฌ์ด๋
- ๋ฉ๋ชจ๋ฆฌ ์ผ๊ด์ฑ ์์คํ
๊ณผ ํจ๊ป ๋๊ฐ์ ์บ์๋ฅผ ๋๊ธฐํ ์์ผ์, ํฌ์ธํฐ ๋ณ๊ฒฝ๊ณผ ์๋ก์ด
- ๋ฐ์ดํฐ์ ๋ฐ๊ฒฌ์ ์ฌ๋ฐ๋ฅธ ์์๋ก ์ผ์ด๋๊ฒ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
- ๋ฆฌ๋
์ค ์ปค๋์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋ชจ๋ธ์ Alpha ์ ๊ธฐ์ดํด์ ์ ์๋์์ต๋๋ค.
- ์์ "์บ์ ์ผ๊ด์ฑ" ์๋ธ์น์
์ ์ฐธ๊ณ ํ์ธ์.
- ๊ฐ์ ๋จธ์ ๊ฒ์คํธ
- ----------------
- ๊ฐ์ ๋จธ์ ์์ ๋์ํ๋ ๊ฒ์คํธ๋ค์ ๊ฒ์คํธ ์์ฒด๋ SMP ์ง์ ์์ด ์ปดํ์ผ ๋์๋ค
- ํด๋ SMP ์ํฅ์ ๋ฐ์ ์ ์์ต๋๋ค. ์ด๊ฑด UP ์ปค๋์ ์ฌ์ฉํ๋ฉด์ SMP ํธ์คํธ์
- ๊ฒฐ๋ถ๋์ด ๋ฐ์ํ๋ ๋ถ์์ฉ์
๋๋ค. ์ด ๊ฒฝ์ฐ์๋ mandatory ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ
- ํด๊ฒฐํ ์ ์๊ฒ ์ง๋ง ๊ทธ๋ฐ ํด๊ฒฐ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ต์ ์ ํด๊ฒฐ์ฑ
์ด ์๋๋๋ค.
- ์ด ๋ฌธ์ ๋ฅผ ์๋ฒฝํ๊ฒ ํด๊ฒฐํ๊ธฐ ์ํด, ๋ก์ฐ ๋ ๋ฒจ์ virt_mb() ๋ฑ์ ๋งคํฌ๋ก๋ฅผ ์ฌ์ฉํ ์
- ์์ต๋๋ค. ์ด๊ฒ๋ค์ SMP ๊ฐ ํ์ฑํ ๋์ด ์๋ค๋ฉด smp_mb() ๋ฑ๊ณผ ๋์ผํ ํจ๊ณผ๋ฅผ
- ๊ฐ์ต๋๋ค๋ง, SMP ์ SMP ์๋ ์์คํ
๋ชจ๋์ ๋ํด ๋์ผํ ์ฝ๋๋ฅผ ๋ง๋ค์ด๋
๋๋ค.
- ์๋ฅผ ๋ค์ด, ๊ฐ์ ๋จธ์ ๊ฒ์คํธ๋ค์ (SMP ์ผ ์ ์๋) ํธ์คํธ์ ๋๊ธฐํ๋ฅผ ํ ๋์๋
- smp_mb() ๊ฐ ์๋๋ผ virt_mb() ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- ์ด๊ฒ๋ค์ smp_mb() ๋ฅ์ ๊ฒ๋ค๊ณผ ๋ชจ๋ ๋ถ๋ถ์์ ๋์ผํ๋ฉฐ, ํนํ, MMIO ์ ์ํฅ์
- ๋ํด์๋ ๊ฐ์ฌํ์ง ์์ต๋๋ค: MMIO ์ ์ํฅ์ ์ ์ดํ๋ ค๋ฉด, mandatory ๋ฐฐ๋ฆฌ์ด๋ฅผ
- ์ฌ์ฉํ์๊ธฐ ๋ฐ๋๋๋ค.
- =======
- ์ฌ์ฉ ์
- =======
- ์ํ์ ๋ฒํผ
- -----------
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด๋ ์ํ์ ๋ฒํผ๋ฅผ ์์ฑ์(producer)์ ์๋น์(consumer) ์ฌ์ด์
- ๋๊ธฐํ์ ๋ฝ์ ์ฌ์ฉํ์ง ์๊ณ ๊ตฌํํ๋๋ฐ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋ ์์ธํ ๋ด์ฉ์
- ์ํด์ ๋ค์์ ์ฐธ๊ณ ํ์ธ์:
- Documentation/circular-buffers.txt
- =========
- ์ฐธ๊ณ ๋ฌธํ
- =========
- Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek,
- Digital Press)
- Chapter 5.2: Physical Address Space Characteristics
- Chapter 5.4: Caches and Write Buffers
- Chapter 5.5: Data Sharing
- Chapter 5.6: Read/Write Ordering
- AMD64 Architecture Programmer's Manual Volume 2: System Programming
- Chapter 7.1: Memory-Access Ordering
- Chapter 7.4: Buffering and Combining Memory Writes
- IA-32 Intel Architecture Software Developer's Manual, Volume 3:
- System Programming Guide
- Chapter 7.1: Locked Atomic Operations
- Chapter 7.2: Memory Ordering
- Chapter 7.4: Serializing Instructions
- The SPARC Architecture Manual, Version 9
- Chapter 8: Memory Models
- Appendix D: Formal Specification of the Memory Models
- Appendix J: Programming with the Memory Models
- UltraSPARC Programmer Reference Manual
- Chapter 5: Memory Accesses and Cacheability
- Chapter 15: Sparc-V9 Memory Models
- UltraSPARC III Cu User's Manual
- Chapter 9: Memory Models
- UltraSPARC IIIi Processor User's Manual
- Chapter 8: Memory Models
- UltraSPARC Architecture 2005
- Chapter 9: Memory
- Appendix D: Formal Specifications of the Memory Models
- UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
- Chapter 8: Memory Models
- Appendix F: Caches and Cache Coherency
- Solaris Internals, Core Kernel Architecture, p63-68:
- Chapter 3.3: Hardware Considerations for Locks and
- Synchronization
- Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching
- for Kernel Programmers:
- Chapter 13: Other Memory Models
- Intel Itanium Architecture Software Developer's Manual: Volume 1:
- Section 2.6: Speculation
- Section 4.4: Memory Access
|