Кіріспе

CPU-ның жадыдағы мәнді, егер ол белгілі бір мәнге тең болса ғана өзгертуге арналған нұсқауы. Компьютер ғылымында, салыстыру және алмастыру (CAS) – көп тізбекті жұмыста синхрондауға қолданылатын атомдық нұсқаулық. Ол жад орнының мазмұнын белгілі бір мәнмен салыстырады және егер олар сәйкес келсе ғана, жад орнының мазмұнын жаңа белгілі бір мәнге өзгертеді. Бұл бір атомдық операция ретінде орындалады. Атомдық операция жаңа мән ең соңғы ақпарат негізінде есептелетініне кепілдік береді; егер мән осы уақыт аралығында басқа тізбекпен өзгертілсе, жазу операциясы сәтсіз аяқталады. Операцияның нәтижесі алмастыру орындалғанын көрсетуі керек; бұл қарапайым логиялық жауап (бұл вариант көбінесе салыстыру және орнату деп аталады) немесе жад орнынан оқылған мәнді қайтару арқылы (жазылған мән емес) жүзеге асырылуы мүмкін.

АБА мәселесі

Кейбір CAS негізделген алгоритмдер жалған оң сәйкестік проблемасына, яки ABA проблемасына ұшырайды және оны шешуі керек. Ескі мән оқылған кезден бастап CAS орындалуға дейін басқа процессорлар немесе жіптер жад орнын екі немесе одан да көп рет өзгертіп, ескі мәнмен сәйкес келетін биттік үлгіге ие болуы мүмкін. Проблема жаңа биттік үлгінің, ол ескі мәнмен бірдей көрінетін, бірақ басқа мағынаға ие болған жағдайда туындайды: мысалы, ол қайта пайдаланылған мекенжай немесе жаңартылған санаушы болуы мүмкін. Бұл мәселені шешудің жалпы жолы – қос ұзындықты CAS (DCAS) қолдану. Мысалы, 32 биттік жүйеде 64 биттік CAS қолданылуы мүмкін. Екінші жартысы санаушыны сақтау үшін пайдаланылады. Операцияның салыстыру бөлігі меңзердің және санаушының бұрын оқылған мәнін ағымдағы меңзер мен санаушымен салыстырады. Егер олар сәйкес келсе, алмасу жүзеге асырылады – жаңа мән жазылады, бірақ жаңа мән санаушысы арттырылған болады. Бұл ABA орын алса, меңзердің мәні бірдей болса да, санаушының да бірдей болуы өте аз мүмкіндікке ие дегенді білдіреді (32 биттік мән үшін 232 операция орындалуы керек, бұл санаушының айналуына себеп болады, және сол сәтте меңзердің мәні де сәйкес келуі керек). Мұның баламалы түрі (DCAS жоқ процессорларда пайдалы) – толық меңзердің орнына бос тізімге кіру индексін пайдалану, мысалы, 32 биттік CAS-пен 16 биттік индекс және 16 биттік санаушыны қолдану. Дегенмен, қысқартылған санаушы ұзындығы заманауи процессорлардың жылдамдығында ABA мүмкіндігін арттыра бастайды. Бұл мәселені жеңілдетуге көмектесетін қарапайым тәсіл – барлық дерек құрылымы үшін жалғыз ABA санаушыны пайдаланудың орнына, әрбір дерек құрылымы элементінде ABA санаушысын сақтау. Күрделірек, бірақ тиімдірек шешім – қауіпсіз жадты қайтаруды (SMR) жүзеге асыру. Бұл, әсерлі түрде, құлыпсыз қоқыс жинау. SMR пайдаланудың артықшылығы – берілген меңзер дерек құрылымында кез келген уақытта бір рет қана болады деген кепілдік, осылайша ABA проблемасы толық шешіледі. (SMR болмаса, дерек құрылымында болмаған жағдайда да барлық дерек элементтеріне қауіпсіз қол жеткізуді қамтамасыз ету үшін бос тізім сияқты нәрсе қолданылады. SMR болғанда, дерек құрылымында тек қазіргі уақытта бар элементтерге ғана қол жеткізіледі).

Шығындар мен пайда

CAS және басқа да атомдық нұсқаулар кейде унипроцессорлық жүйелерде қажет емес деп есептеледі, себебі кез келген нұсқаулар тізбегінің атомарлығын орындау кезінде үзілістерді өшіру арқылы қамтамасыз етуге болады. Дегенмен, үзілістерді өшірудің көптеген кемшіліктері бар. Мысалы, мұндай рұқсатқа ие коддың қасақана зиян келтірмейтініне және процессорды монополияламайтынына, сондай-ақ дұрыс жұмыс істейтініне және машинаны шексіз циклге немесе жад қатесіне кездейсоқ түсірмейтініне сенім білдіру қажет. Бұған қоса, үзілістерді өшіру көбінесе өте қымбатқа түседі, сондықтан тәжірибеде тиімді емес. Осылайша, тіпті тек унипроцессорлық машиналарда жұмыс істеуге арналған бағдарламалар да, Linux-тың futex-тері сияқты, атомдық нұсқаулардан пайда көреді. Көппроцессорлық жүйелерде барлық процессорларда бір уақытта үзілістерді өшіру әдетте мүмкін емес. Егер мүмкін болса да, екі немесе одан көп процессор бір мезгілде бір семафордың жадына қол жеткізуге тырысуы мүмкін, нәтижесінде атомарлыққа қол жеткізілмейді. Салыстыру және алмастыру нұсқаулығы кез келген процессорға жад орнын атомарлық түрде тексеруге және өзгертуге мүмкіндік береді, осылайша бірнеше процессордың қақтығысуына жол бермейді. 2010 жылдардың серверлік деңгейдегі көппроцессорлық архитектураларында салыстыру және алмастыру, кэштен алынбаған қарапайым жүктемеге қарағанда арзан. 2013 жылғы мақалада CAS Intel Xeon (Westmere EX) процессорларында кэштелмеген жүктемеден 1,15 есе, ал AMD Opteron (Magny Cours) процессорларында 1,35 есе қымбат екені көрсетілген.

Қолданылу

Салыстыру және айырбастау (және екі рет салыстыру және айырбастау) 1970 жылдан бері IBM 370 (және оның барлық ұрпақтары) архитектурасының ажырамас бөлігі болып келді. Бұл архитектуралардағы операциялық жүйелер процестерді (яғни, жүйелік және пайдаланушы тапсырмаларын) және процессорларды (яғни, орталық процессорларды) параллельдетуді жеңілдету үшін осы нұсқауды кеңінен пайдаланады, сонымен қатар бұрынғы IBM операциялық жүйелерінде қолданылған "мүмкін болғанша толығымен жойылған" "тоқтатылған спин-құлыптарды" болдырмайды. Сондай-ақ, тест және орнату әдісі де қолданудан шығарылды. Бұл операциялық жүйелерде жаңа жұмыс бірліктері бір салыстыру және айырбастау нұсқауын орындау арқылы "глобалды" түрде, яғни, жаһандық қызметтік басымдық тізіміне немесе "жергілікті" түрде, яғни, жергілікті қызметтік басымдық тізіміне енгізіле алады. Бұл операциялық жүйелердің жауап беру жылдамдығын едәуір арттырды. x86 (80486-дан бастап) және Itanium архитектураларында бұл салыстыру және алмастыру (CMPXCHG) нұсқауы ретінде жүзеге асырылады (көппроцессорлық жүйеде префикс қолданылуы тиіс). 2013 жылғы мәліметтер бойынша, көптеген көппроцессорлық архитектуралар аппараттық деңгейде CAS-ты қолдайды, ал салыстыру және айырбастау операциясы – бұғаттағыш және бұғаттамайтын параллель деректер құрылымдарын іске асыру үшін ең танымал синхрондау примитиві болып табылады.

Ұзартулар

CAS бір ғана көрсеткіш өлшемімен жад орнында жұмыс істейтіндіктен, ал көптеген құлыптаусыз және күтусіз алгоритмдер бірнеше орындарды өзгертуді қажет ететіндіктен, бірнеше кеңейтулер енгізілді. Қос салыстыру және алмастыру (DCAS) екі байланыссыз жад орнын екі күтілетін мәнмен салыстырады, егер олар тең болса, екі орынды да жаңа мәндерге орнатады. DCAS-ті бірнеше (іргелес емес) сөздерге жалпылау MCAS немесе CASN деп аталады. DCAS және MCAS кейбір дерек құрылымдарын, мысалы, екі ұшталған тізімдерді немесе екілік іздеу ағаштарын ыңғайлы (параллель) жүзеге асыруда практикалық маңызға ие. DCAS және MCAS кейбір соңғы процессорларда, мысалы IBM POWER8 немесе транзакциялық синхронизациялық кеңейтулерді (TSX) қолдайтын Intel процессорларындағы аппараттық транзакциялық жадты пайдалана отырып жүзеге асырылуы мүмкін. Екі есе кең салыстыру және алмастыру екі іргелес көрсеткіш өлшеміндегі (немесе, балама ретінде, көрсеткіштен екі есе үлкен бір орында) жұмыс істейді. Жаңа x86 процессорларында CMPXCHG8B және CMPXCHG16B нұсқаулары осы рөлді атқарады, бірақ ерте 64 биттік AMD процессорлары CMPXCHG16B-ді қолдамады (қазіргі AMD процессорлары қолдайды). Кейбір Intel аналық платалары Core 2 дәуірінен бастап оны қолдануға кедергі келтіреді, тіпті процессорлар оны қолдайтын болса да. Бұл мәселелер Windows 8.1 іске қосылған кезде назарға алынды, өйткені ол CMPXCHG16B үшін аппараттық қолдауды талап етті. Бір салыстыру, екі алмастыру бір көрсеткішті салыстырады, бірақ екі жазба жасайды. Itanium-ның cmp8xchg16 нұсқауы осыны жүзеге асырады, онда екі жазба көрсеткіші іргелес орналасқан. Көп сөзді салыстыру және алмастыру – бұл қалыпты салыстыру және алмастырудың жалпылауы. Оны кез келген орналасқан жад орындарындағы кез келген санды атомдық түрде алмастыру үшін пайдалануға болады. Әдетте, көп сөзді салыстыру және алмастыру бағдарламалық жасақтамада қарапайым екі есе кең салыстыру және алмастыру операцияларын пайдалана отырып жүзеге асырылады. Бұл тәсілдің кемшілігі – оның кеңейтімге қабілетсіздігі. Тұрақты салыстыру және алмастыру – бұл тұрақты операция мен қалыпты салыстыру және алмастырудың үйлесімі. Оны мәнді атомдық түрде салыстыру және алмастыру үшін пайдалануға болады, содан кейін мәнді сақтауға болады, сондықтан параллель көріну мен апат көріну арасында үзіліс болмайды. Бұл кеңейту тұрақсыз жазуды оқу мәселесін шешеді.

CAS-ты қолдана отырып іске асырылған негізгі алгоритмдер

2003 жылғы Intel x86 процессорларында "cmpxchg8b арқылы құлыптаусыз қол жеткізу" талқылауы, түрлі мақалалар мен бастапқы кодқа сілтемелермен.