Memory model — dasturlash tili, compiler va apparatning memory read hamda write amallari, ularning tartibi va threadlar orasida ko‘rinishi haqidagi qoidalaridir. U concurrent dastur qaysi natijalarni qonuniy olishi mumkinligini belgilaydi. Source’dagi satr tartibi boshqa thread aynan shu tartibda o‘zgarishlarni ko‘rishini avtomatik anglatmaydi.
Reordering
Compiler observable single-thread semantikani saqlagan holda instructionlarni qayta tartiblashi mumkin. CPU out-of-order execution va store buffer orqali performance oshiradi. Bir thread uchun farq ko‘rinmasa ham synchronization bo‘lmagan boshqa thread oraliq holatni ko‘rishi mumkin.
Memory model compilerga ruxsat etilgan optimization va dasturchiga beriladigan kafolat chegarasini belgilaydi. Juda kuchli model hardware performance’ni cheklashi, juda zaif model esa reasoningni qiyinlashtirishi mumkin.
Data race
Ikki thread bir memory locationga bir vaqtda murojaat qilib, kamida biri write qilsa va ular synchronization bilan tartiblanmagan bo‘lsa data race yuz beradi. Ayrim tillarda bu undefined behavior, boshqalarida ma’lum zaif semantika beradi. Race condition kengroq tushuncha bo‘lib, atomik operationlar bilan ham logical tartib xatosi yuz berishi mumkin.
Thread sanitizer developmentda race’larni dynamic aniqlaydi, lekin bajarilmagan interleavingni ko‘rmaydi. Lock discipline va ownership design asosiy himoya bo‘lib qoladi.
Happens-before
Happens-before bir operation natijasi boshqasiga ko‘rinishini kafolatlaydigan qisman tartibdir. Program order, lock release-acquire, thread start/join yoki atomic synchronization edge yaratishi mumkin. Agar write read’dan oldin happens-before bo‘lsa, model tegishli visibility kafolatini beradi.
Wall-clock vaqt yoki logda oldin ko‘ringan hodisa formal happens-before bo‘lishi shart emas. Distributed systemdagi causal order boshqa qatlam, lekin o‘xshash reasoningga ega.
Atomic operation
Atomic read-modify-write oraliq holatsiz bitta indivisible amal sifatida ko‘rinadi. Compare-and-swap lock-free algorithmning asosidir. Atomicity o‘zi orderingni to‘liq bermaydi; relaxed, acquire, release va sequentially consistent ordering variantlari mavjud.
Eng kuchli orderingni hamma joyda ishlatish tushunarli, ammo performance narxi bo‘lishi mumkin. Zaif ordering faqat proof va benchmark bilan qo‘llanadi. Comment qaysi invariant va pairingga tayanganini tushuntiradi.
Cache va false sharing
Hardware cache coherence bitta locationning qiymatini muvofiqlashtiradi, lekin source-level race’ni xavfsiz qilmaydi. Ikki thread alohida variablega yozsa ham ular bir cache line’da bo‘lsa false sharing trafik va sekinlik keltiradi. Padding performance uchun ishlatilishi mumkin, ammo platforma o‘lchamiga bog‘liq.
Volatile keywordning ma’nosi tilga xos. Ba’zi tilda device memory yoki optimizationni cheklaydi, lekin thread synchronization bermaydi. Universal “volatile thread-safe qiladi” qoidasi mavjud emas.
Safe publication
Object yaratilgach uning reference’ini boshqa threadga synchronization bilan berish kerak. Noto‘g‘ri publication boshqa threadga constructor yozuvlarining bir qismini ko‘rsatishi mumkin. Immutable object va final-field kafolatlari til memory modeliga bog‘liq.
Double-checked locking tarixan zaif memory modelda broken bo‘lgan; tegishli atomic yoki volatile semantics bo‘lmasa reference initialized data’dan oldin ko‘rinadi. Tayyor concurrency primitive ishlatish qo‘lda barrier yozishdan xavfsizroq. Lock-free algorithm ABA muammosi va memory reclamationni ham hal qilishi kerak. Hazard pointer yoki epoch-based reclamation o‘chirilgan node’ni boshqa thread o‘qiyotgan paytda bo‘shatishni cheklaydi.
Memory modelga oid xatolar odatda kam takrorlanadigan bo‘lgani uchun stress test turli yadro soni va arxitekturalarda bajariladi. Thread sanitizer kabi vositalar data race’larni topishga yordam beradi, ammo modeldagi barcha ordering xatosini isbotlab bermaydi.
Bog‘liq tushunchalar
Concurrency, Data race, Happens-before, Atomic operation, Memory barrier, Cache coherence, Lock-free programming