Processoraffinitet , eller processoraffinitet , eller cache - affinitet , är en teknik som säkerställer att en process eller tråd fästs och kopplas bort till en specifik CPU-kärna, CPU eller uppsättning processorer, så att processen eller tråden bara körs på den angivna kärnan , processor eller processorer, och inte på någon processor i ett multiprocessorsystem. Processoraffinitet kan ses som en modifiering av den centrala uppgiftsköschemaläggningsalgoritmen i ett multiprocessoroperativsystem. Varje objekt i uppgiftskön har en tagg associerad med sig, som anger dess "relaterade" processorer.
När resurser tilldelas fördelas varje uppgift företrädesvis för exekvering på en av de "relaterade" processorerna. Processoraffinitet utnyttjar det faktum att data och inställningar för en process som tidigare kördes på en given processor kan vara snabbare tillgängliga för den processorn än för en annan. Detta kan till exempel hända på grund av cachelagring av processdata i processorcachen, såväl som i vissa andra situationer. Att schemalägga en sådan process för att köras på samma processor förbättrar dess prestanda genom att minska prestandaförsämrande händelser som cacheförluster.
Dessutom, i vissa system, kan var och en av processorerna ha snabbare åtkomst till en region med RAM som är nära den. Samtidigt visar det sig vara rationellt att hålla en konstant bindning av processen till processorn, vars åtkomst till RAM, där data från denna process finns, är snabbare.
Ett praktiskt exempel på processoraffinitet är att köra flera instanser av en icke-trådad applikation, till exempel en del grafikåtergivningsprogram.
Implementeringen av uppgiftsschemaläggningsalgoritmen, som ger möjligheten att binda till processorn, implementeras med hänsyn till egenskaperna hos specifika processorer och konstruktionen av ett multiprocessorsystem, som kommer att styras av en sådan algoritm. Vissa implementeringar kommer under vissa omständigheter att tillåta en uppgift att överföras till en annan processor och övervinna bindningen. Detta görs i de fall då, ur schemaläggarens synvinkel, en sådan växling kommer att leda till en ökning av effektiviteten av uppgiftsexekveringen. Till exempel, när två processorintensiva uppgifter (A och B) är bundna till samma processor och den andra processorn inte används, kommer många schemaläggare att byta uppgift B till den andra processorn för att få ut det mesta av processorn tillgänglig för systemet . Bindningen av uppgift B till den nya processorn vid ett sådant ögonblick kommer att ställas in av schemaläggaren själv.
Processoraffinitet kan effektivt minska problem med att data kommer in i systemet och/eller processorcachen. Men det ger ingen lösning på lastbalanseringsproblem [1] . CPU-affinitet är mer komplex i system med en heterogen arkitektur, vilket kräver mer sofistikerad schemaläggningslogik än i helt homogena system. Till exempel, ett system med två processorer med dubbla kärnor , som var och en stöder Hyper-Threading-teknik , utgör ett problem för schemaläggningsalgoritmen, som antar CPU-affinitet. Om systemet har ett ännu större antal processorer, och till exempel inte är helt symmetriskt i sig, så ökar komplexiteten i problemet med effektiv uppgiftsschemaläggning ännu mer.
För exemplet ovan med två hypertrådade dubbelkärniga processorer måste schemaläggaren implementera ett tvånivåbindningssystem. När det gäller cacheeffektivitet är arbete inom samma kärna på olika trådar likvärdigt, och schemaläggaren har rätt att fritt flytta en uppgift från tråd till tråd. Nivån av "närhet" för olika kärnor inom en processor är lägre, eftersom de delvis delar en gemensam processorcache, är nivån av "närhet" för olika processorer ännu lägre. Eftersom andra resurser också delas kan CPU-affinitet inte enbart användas som grund för uppgiftsschemaläggning. Till exempel, om en process nyligen kördes på en virtuell hyper-threading CPU i någon kärna, och den virtuella CPU:n för närvarande är upptagen, men en andra virtuell CPU av samma kärna är inaktiv, innebär cpu-affinitet baserad på cacheeffektivitet att processen måste överföras till en andra (ej igång) virtuell processor med samma kärna. De två virtuella CPU:erna konkurrerar dock om nästan alla datorresurser, cacheminne och minnesresurser. I denna situation skulle det som regel vara mer effektivt att tilldela processen till en annan kärna eller CPU, om det finns lediga bland dem. Detta kan resultera i en engångsprestandaträff på grund av att den omlokaliserade processen måste fylla på cachen med dess data igen. Men den övergripande prestandan kan bli bättre eftersom de två processerna inte behöver konkurrera om resurser inom samma CPU.
För att uppnå maximal effektivitet måste uppgiftsschemaläggaren ta hänsyn till alla dessa aspekter. System med ännu högre nivåer av asymmetri ( NUMA , kluster, etc.) kräver ännu mer komplexitet från schemaläggaren.
På Linux kan en processs processoraffinitet hittas eller ställas in med hjälp av taskset-verktyget [2] . Programmatiskt kan samma åtgärder utföras med systemanropen sched_getaffinity och sched_setaffinity [3] . Trådaffiniteten kan ställas in eller ändras med en av biblioteksfunktionerna: pthread_setaffinity_np [4] eller pthread_attr_setaffinity_np [5] .
På SGI- system kan en process associeras med en uppsättning processorer som använder dplace- verktyget [6] .
I DragonFly BSD 1.9 (2007) och senare kan systemanropet usched_set [7] [8] användas för att kontrollera CPU-affinitet . I NetBSD 5.0, FreeBSD 7.2, DragonFly BSD 4.7 och senare kan systemanropen pthread_setaffinity_np och pthread_getaffinity_np [9] användas . I NetBSD ställer [10] psrset-verktyget en tråds affinitet till en specifik uppsättning processorer. FreeBSD använder verktyget cpuset [11] för att skapa uppsättningar av processorer och tilldela processer till dessa uppsättningar. I DragonFly BSD 3.1 (2012) och senare kan usched-verktyget användas för att tilldela processer till en specifik uppsättning processorer [12] .
På Windows NT och senare kan tråd- och processaffiniteter ställas in separat med hjälp av SetThreadAffinityMask [13] och SetProcessAffinityMask [14] API-anrop eller via Task Manager-gränssnittet (endast för processer).
macOS tillhandahåller ett bindnings-API [15] som ger tips till OS-kärnan om hur man schemalägger trådar enligt bindningsuppsättningar.
På Solaris kan du styra bindningen av processer och lätta processer till processorn med hjälp av verktyget pbind [16] . Systemanropet processor_bind [17] tillhandahålls också . Gränssnittsanrop på högre nivå är också tillgängliga, nämligen pset_bind [18] eller lgrp_affinity_get [19] , med begreppen processoruppsättning respektive lokalitetsgrupp.
På AIX kan du hantera processbindningar med hjälp av bindprocessor [20] [21] verktyg och bindprocessor [20 ] [ 22 ] systemanrop .
z/OS implementerar kanske den mest sofistikerade uppgiftsschemaläggaren som används idag. Det ger en dynamiskt föränderlig omfördelning av hårdvaruresurser mellan processer, inklusive de som är baserade på bindning av processer till individuella processorkärnor, processorer och deras grupper [23]
Standardbiblioteket för det parallella programmeringsspråket Julia inkluderar experimentellt stöd för process-till-processor-affinitet [24] .