Atomisk drift
Atomisk ( grekiska άτομος - odelbar) operation - en operation som antingen utförs helt eller inte alls; en operation som inte kan utföras delvis och delvis inte utföras.
Den här artikeln beskriver de enklaste atomoperationerna (läsa, skriva, etc.), även om termen kan syfta på operationer på högre nivå, som till exempel en serie frågor till DBMS inom en enda transaktion .
Atomoperationer används i multiprocessordatorer och i multitasking - operativsystem för att ge åtkomst för flera processer och/eller flera trådar i samma process till resurser som delas mellan dem. En atomoperation utförs av endast en tråd .
Klassificering
Atomiciteten av operationer kan tillhandahållas av hårdvara (hårdvara) och programvara (programkod). I det första fallet används speciella maskininstruktioner , vars atomicitet garanteras av hårdvaran. I det andra fallet används speciella synkroniseringsprogramvaruverktyg , med hjälp av vilka den delade resursen är låst ; efter blockering utförs operationen som behöver göras atomärt. Ett lås är en atomär operation som antingen beviljar en resurs till en tråd eller berättar för tråden att resursen redan används av en annan tråd eller process (upptagen).
Monteringsanvisningar och atomicitet
Maskininstruktioner, vars utförande alltid kan betraktas som atomär:
- maskininstruktioner för att läsa data från minnet på en inriktad adress och skriva den till ett allmänt register;
- maskininstruktioner för att läsa data från ett allmänt register och skriva det till minnet på en anpassad adress;
- maskininstruktioner speciellt utformade för att fungera atomärt, vanligtvis kallade atominstruktioner.
Maskininstruktioner som inte är atomära:
- maskininstruktioner för att läsa/skriva data på en ojusterad adress (genom att exekvera en av dessa instruktioner tvingas processorn att komma åt två minnesceller. I det ögonblick då processorn kommer åt en cell kan den andra cellen ändras av en annan processor);
- alla maskininstruktioner i formen " läs-ändra-skriv " (utförande av en sådan instruktion reduceras till att läsa data från minnet, ändra data till ALU och skriva data till minnet. Efter att ha läst data från minnet kan innehållet i minnet ändras);
- strängmaskininstruktioner för x86-processorer ;
- push och pop maskininstruktioner för x86-processorer;
- maskininstruktioner som fungerar med speciella kontrollregister (sådana instruktioner kan exekveras inom flera processorcykler och generera tiotals eller hundratals minnesåtkomster, de används endast i systemprogramvara ) .
Atominstruktioner för x86-processorer
Atominstruktioner för x86- arkitekturprocessorer :
- CMPXCHG, CMPXCHG8B, CMPXCHG16B är den huvudsakliga atominstruktionen för x86-processorer som utför jämförelse och utbyte . När den används med prefixet LOCK [1] [2] jämförs atomärt värdet av en variabel med det angivna värdet och, beroende på resultatet av jämförelsen, antingen ställer det angivna värdet till variabeln eller gör ingenting. Det är grunden för implementeringen av alla icke-blockerande algoritmer , som ofta används i implementeringen av spinlocks , RWLocks och nästan alla synkroniseringselement på hög nivå, såsom semaforer, mutexer, händelser, etc.;
- XCHG är en operation för utbyte av data mellan ett register och en minnescell, eller mellan två register. Atomiciteten för denna operation har betydelse när instruktionsoperanden är en minnescell. På x86- processorer körs den atomärt även utan att använda prefixet LOCK [3] (av denna anledning bör man undvika att använda denna instruktion för att utbyta värden för ett register och en minnesplats, detta kommer att orsaka onödiga och mycket betydande förseningar i kodexekvering). Används ofta i implementeringen av spinlocks .
Dessutom exekveras många läs-modifiera-skriv maskininstruktioner atomiskt när de prefixeras med LOCK [4] ( opcode 0xF0), såsom följande:
- additions- och subtraktionskommandon ADD, ADC, SUB och SBB om destinationsoperanden är adressen till en minnescell;
- inkrementera och minska kommandona INC och DEC;
- logiska kommandon AND, OR och XOR;
- enkla operandinstruktioner NEG och NOT;
- bitoperationer BTS, BTR och BTC;
- additions- och utbytesoperation XADD.
LOCK-prefixet låser minnesåtkomst under instruktionens varaktighet. Ett lås kan sträcka sig över ett minnesområde som är bredare än längden på operanden, till exempel längden på en cache -linje .
Atominstruktioner i RISC-processorer
En egenskap hos RISC -processorarkitekturer är frånvaron av läs-modifiera-skriv- instruktioner . DEC Alpha , PowerPC , MIPS och ARM (ARMv6 och äldre) RISC-processorer stöder icke-blockerande exklusiv minnesåtkomst. Atomoperationer implementeras med ett par exklusiva läs-skrivinstruktioner LL och SC enligt följande:
- lastning med ett märke (LL - last länkad);
- dataändring;
- skrivförsök (SC - lagra villkorlig).
Den första instruktionen (LL) laddar data från minnesplatsen till ett register och markerar platsen som en plats för exklusiv åtkomst. Därefter görs nödvändiga dataändringar i registret. Att skriva data från registret till minnet (SC) utförs endast om minnescellens värde inte har ändrats. Om värdet har ändrats måste de tre operationerna (LL, dataändring och SC) upprepas.
Atominstruktioner och kompilatorer
Kompilatorer av högnivåspråk använder som regel inte atominstruktioner när de genererar kod, eftersom för det första atomoperationer är många gånger mer resurskrävande än vanliga, och för det andra har kompilatorn ingen information om när dataåtkomst ska utföras atomärt (eftersom även den flyktiga modifieraren för en variabel i C/C++ betyder inte ett verkligt behov av att använda atomoperationer). Om det behövs kan programmeraren använda atominstruktioner på något av följande sätt:
- infoga atominstruktioner i koden med hjälp av assemblern som tillhandahålls av kompilatorn , till exempel GCC Inline Assembly för gcc- kompilatorn ;
- använd kompilatorförsedda funktioner som anropar atominstruktioner, såsom funktioner i familjerna __builtin_ eller __sync_ i gcc- kompilatorn ;
- använda funktioner som tillhandahålls av bibliotek som anropar atominstruktioner, till exempel funktioner i Glib- biblioteket ;
- använd programmeringsspråk som stöder atomicitet, såsom standardspråken C11 och C++14 som stöder _atom- och atomtyperna och funktionerna i atomfamiljen [5] .
Se även
Anteckningar
- ↑ CMPXCHG - Jämför och byt Arkiverad 2 november 2012 på Wayback Machine .
- ↑ CMPXCHG8B - Jämför och byt ut 8 bytes Arkiverad 30 november 2012 på Wayback Machine .
- ↑ http://faydoc.tripod.com/cpu/xchg.htm Arkiverad 20 november 2012 på Wayback Machine "Om en minnesoperand refereras, implementeras processorns låsprotokoll automatiskt under utbytesoperationens varaktighet, oavsett närvaron eller frånvaron av LOCK-prefixet eller värdet på IOPL."
- ↑ Atomoperationer. Frågans historia . Hämtad 12 november 2012. Arkiverad från originalet 17 november 2012. (obestämd)
- ↑ Atomic operations library - cppreference.com . Hämtad 12 november 2012. Arkiverad från originalet 13 augusti 2015. (obestämd)
Länkar