Atomisk drift
Atomisk ( græsk άτομος - udelelig) operation - en operation, der enten udføres helt eller slet ikke udføres; en operation, der ikke kan udføres delvist og delvist ikke udføres.
Denne artikel beskriver de enkleste atomoperationer (læse, skrive osv.), selvom begrebet kan henvise til operationer på højere niveau, såsom for eksempel en række forespørgsler til DBMS inden for en enkelt transaktion .
Atomiske operationer bruges i multiprocessor -computere og i multitasking -operativsystemer for at give adgang til flere processer og/eller flere tråde i den samme proces til ressourcer, der deles mellem dem. En atomoperation udføres kun af én tråd .
Klassifikation
Atomiciteten af operationer kan tilvejebringes af hardware (hardware) og software (programkode). I det første tilfælde anvendes specielle maskininstruktioner , hvis atomicitet er garanteret af hardwaren. I det andet tilfælde bruges specielle synkroniseringssoftwareværktøjer , ved hjælp af hvilke den delte ressource er låst ; efter blokering udføres den operation, der skal udføres atomisk. En lås er en atomoperation, der enten giver en ressource til en tråd eller fortæller tråden, at ressourcen allerede er i brug af en anden tråd eller proces (optaget).
Monteringsvejledning og atomicitet
Maskininstruktioner, hvis udførelse altid kan betragtes som atomare:
- maskininstruktioner til at læse data fra hukommelsen på en tilpasset adresse og skrive dem til et generelt register;
- maskininstruktioner til at læse data fra et almindeligt register og skrive det til hukommelsen på en tilpasset adresse;
- maskininstruktioner specielt designet til at fungere atomisk, almindeligvis omtalt som atominstruktioner.
Maskininstruktioner, der ikke er atomare:
- maskininstruktioner til læsning/skrivning af data på en ujusteret adresse (ved at udføre en af disse instruktioner tvinges processoren til at få adgang til to hukommelsesceller. I det øjeblik, hvor processoren tilgår én celle, kan den anden celle ændres af en anden processor);
- alle maskininstruktioner af formen " læs-modificer-skriv " (udførelse af en sådan instruktion reduceres til at læse data fra hukommelsen, ændre data til ALU'en og skrive data til hukommelsen. Efter at have læst data fra hukommelsen kan indholdet af hukommelsen ændre sig);
- streng maskininstruktioner til x86-processorer ;
- push og pop maskininstruktioner til x86-processorer;
- maskininstruktioner, der arbejder med specielle kontrolregistre (sådanne instruktioner kan udføres inden for flere processorcyklusser og generere titusindvis eller hundredvis af hukommelsesadgange, de bruges kun i systemsoftware ) .
Atomic instruktioner til x86-processorer
Atomic instruktioner til x86 arkitektur processorer :
- CMPXCHG, CMPXCHG8B, CMPXCHG16B er den vigtigste atominstruktion for x86-processorer , der udfører sammenligning og udveksling . Når det bruges med LOCK [1] [2] præfikset , sammenligner atomisk værdien af en variabel med den specificerede værdi og, afhængigt af resultatet af sammenligningen, enten indstiller den specificerede værdi til variablen eller gør ingenting. Det er grundlaget for implementeringen af alle ikke-blokerende algoritmer , ofte brugt i implementeringen af spinlocks , RWLocks og næsten alle synkroniseringselementer på højt niveau, såsom semaforer, mutexes, begivenheder osv.;
- XCHG er en operation til udveksling af data mellem et register og en hukommelsescelle eller mellem to registre. Atomiciteten af denne operation har betydning, når instruktionsoperanden er en hukommelsescelle. På x86- processorer udføres den atomært selv uden brug af LOCK [3] præfikset (af denne grund bør det undgås at bruge denne instruktion til at udveksle værdier af et register og en hukommelsesplacering, dette vil forårsage unødvendige og meget betydelige forsinkelser i kodeudførelse). Bruges ofte til implementering af spinlocks .
Derudover udføres mange læs-modificer-skriv maskininstruktioner atomisk, når de er præfikset med LOCK [4] ( opkode 0xF0), såsom følgende:
- additions- og subtraktionskommandoer ADD, ADC, SUB og SBB, hvis destinationsoperanden er adressen på en hukommelsescelle;
- inkrement og decrement kommandoer INC og DEC;
- logiske kommandoer AND, OR og XOR;
- enkelt operand instruktioner NEG og NOT;
- bitoperationer BTS, BTR og BTC;
- additions- og udvekslingsoperation XADD.
LOCK-præfikset låser hukommelsesadgang under instruktionens varighed. En lås kan strække sig over et hukommelsesområde, der er bredere end længden af operanden, såsom længden af en cache -linje .
Atominstruktioner i RISC-processorer
En funktion ved RISC -processorarkitekturer er fraværet af læse-modificere-skrive- instruktioner . DEC Alpha , PowerPC , MIPS og ARM (ARMv6 og ældre) RISC-processorer understøtter ikke-blokerende eksklusiv hukommelsesadgang. Atomiske operationer implementeres ved hjælp af et par eksklusive læse-skrive-instruktioner LL og SC som følger:
- læsning med et mærke (LL - belastning forbundet);
- dataændring;
- skriveforsøg (SC - gem betinget).
Den første instruktion (LL) indlæser dataene fra hukommelseslokationen i et register og markerer lokationen som en lokation for eksklusiv adgang. Dernæst foretages de nødvendige dataændringer i registret. Skrivning af data fra registret til hukommelsen (SC) udføres kun, hvis værdien af hukommelsescellen ikke er ændret. Hvis værdien er ændret, skal de tre operationer (LL, dataændring og SC) gentages.
Atominstruktioner og kompilatorer
Kompilere af højniveausprog bruger som regel ikke atominstruktioner, når de genererer kode, fordi for det første er atomoperationer mange gange mere ressourcekrævende end almindelige, og for det andet har compileren ingen information om, hvornår dataadgang skal udføres atomært (fordi selv den flygtige modifikator for en variabel i C/C++ betyder ikke et reelt behov for at bruge atomoperationer). Om nødvendigt kan programmøren bruge atominstruktioner på en af følgende måder:
- indsæt atominstruktioner i koden ved hjælp af assembleren leveret af compileren , for eksempel GCC Inline Assembly af gcc compileren ;
- brug compiler-leverede funktioner, der kalder atominstruktioner, såsom funktioner i __builtin_ eller __sync_ familierne af gcc compileren ;
- bruge funktioner leveret af biblioteker , der kalder atominstruktioner, for eksempel funktioner i Glib- biblioteket ;
- brug programmeringssprog, der understøtter atomicitet, såsom standardsprogene C11 og C++14 , der understøtter _atom- og atomtyperne og funktionerne i atomfamilien [5] .
Se også
Noter
- ↑ CMPXCHG - Sammenlign og udveksle Arkiveret 2. november 2012 på Wayback Machine .
- ↑ CMPXCHG8B - Sammenlign og udskift 8 bytes Arkiveret 30. november 2012 på Wayback Machine .
- ↑ http://faydoc.tripod.com/cpu/xchg.htm Arkiveret 20. november 2012 på Wayback Machine "Hvis der henvises til en hukommelsesoperand, implementeres processorens låseprotokol automatisk under udvekslingsoperationens varighed, uanset tilstedeværelsen eller fraværet af LOCK-præfikset eller værdien af IOPL."
- ↑ Atomoperationer. Problemets historie . Hentet 12. november 2012. Arkiveret fra originalen 17. november 2012. (ubestemt)
- ↑ Atomic operations library - cppreference.com . Hentet 12. november 2012. Arkiveret fra originalen 13. august 2015. (ubestemt)
Links