Apple arrangerar för närvarande utvecklarevenemanget WWDC 2020, där utvecklare ges insikt i de nya operativsystemen som når Apples produktutbud till hösten. I år sker dock en större händelse i form av att Apple aviserar övergången från Intel-processorer till egenbyggda ARM-varianter, en övergång som sker över kommande två år.

I en videogenomgång förklarar Apples mjukvaruingenjör Kuba Mracek hur utvecklare kan skapa applikationer för Apples ARM-baserade applikationer, vars underliggande arkitektur kallas Arm64. I genomgången förklaras också hur Intels instruktionsuppsättning x86-64 skiljer sig åt från Arm64, och hur problem undviks när mjukvara ska portas mellan de båda grundstommarna.

Apple_Arm64-1.jpg
Apple_Arm64-4.jpg
Apple_Arm64-6.jpg

Enligt Apple kan kod för x86-64 köras emulerat på Apples Arm64-processorer helt utan problem, så länge som inga Intel-specifika instruktioner eller tillägg används. Utvecklare kan välja att kompilera sin kod för Intel, Apple Arm64 eller båda två. Om det senare alternativet väljs skapas universella binära körfiler enligt formatet Universal 2. De universella körfilerna skapas enligt formatet Mach-O, där de kan vara byggda för en specifik processortyp eller vara universella.

Apple rekommenderar att alla applikationer som skapas från och med nu ska kompileras som universella körfiler. När det kommer till emulering av gammal kod via Rosetta 2 förklarar Apple att en applikation för Arm64 körs antingen som systemäkta (eng. native) eller emulerad, en blandning är alltså inte möjlig. För utvecklare som vill porta gammal 64-bitarskod för Intel-processorer finns det några kodtyper som inte fungerar.

Apple_Arm64-2.jpg
Apple_Arm64-8.jpg
Apple_Arm64-7.jpg
Apple_Arm64-17.jpg

Utökningar av operativsystemets kärna (kernel extensions) fungerar inte, och inte heller Intels AVX-vektorinstruktioner. Applikationer som utvecklats för IOS och A-seriens processorer är med största sannolikhet redan portade till Arm64, och kräver därmed ingen anpassning av koden. En skillnad mellan Intels x86-64 och Arm64 som noteras i videogenomgången är att de båda processortyperna skiljer sig åt i hur de hanterar virtuellt minne (eng. page size). För Intel är storleken fixerad vid 4 kB medan Apples implementation av Arm64 använder 16 kB.

Utvecklare hanterar detta antingen genom att ange en maximal storlek, eller ange en specifik page size-storlek. Kod som körs under Rosetta 2-emulering får automatiskt Intels 4 kB-storlek tilldelat. För utvecklare som vill porta Intel-kod till systemäkta Arm64-kod visar videogenomgången på några fel som troligtvis kan dyka upp. Ett exempel är när utvecklare specificerat processortyp för logiska beroenden i kod (eng. conditionals).

Apple_Arm64-19.jpg
Apple_Arm64-20.jpg

Exempel på icke-kompatibel kod som specificerar Intels x86-64.

Apple_Arm64-18.jpg

Här har istället Mac OS med Objective-C-kod angivits som mål för koden.

Om en utvecklare anger x86-64 för ett if-beroende kommer detta ge felmeddelande vid kompilering för systemäkta Arm64-applikationer. För att undvika problemet ska utvecklare istället ange operativsystemet som mål, med OS_OSX som mål för Objective-C-kod och macOS som mål för Swift-kod. Det är fortfarande möjligt att ange specifika arkitekturer och operativsystem som mål likt tidigare, men ovan metod säkerställer att koden kompileras för alla stödda arkitekturer.

I de fall där processorspecifika funktioner och instruktioner används bör dessa kapslas in i logiska if-satser, som vidarebefordrar till en andra implementation för Arm64 om en sådan processor upptäcks. Apple uppmanar dock utvecklare att använda de funktioner och ramverk som ingår i Mac OS, då dessa är kompatibla med alla processorer operativsystemet körs på. Kodprojekt som innehåller förkompilerade binära filer behöver också kontrollera att dessa inte innehåller kod och symboler specifika för x86-64.

Apple_Arm64-14.jpg
Apple_Arm64-11.jpg

De Intel-specifika instruktioner som stöds kan skrivas och användas i Xcode, och dessa översätts i bakgrunden till Arm64-kod via Rosetta 2-stödet i Xcode 12. Då Arm64 delar egenskaper med x86-64 sett till hur de hanterar ordningen av bitar från primärminnet under körning, vilket konceptuellt kallas "endianness", behöver utvecklare inte oroa sig för hur bitar hanteras. Detta till skillnad från Apples övergång från PowerPC till Intel-arkitekturer, vars "endianness"-egenskaper skiljer sig åt.

När processer granskas visas processortypen som kort och gott Apple, vilket visar att koden körs systemäkta (eng. native) på bolagets Arm64-processorer. När mjukvara kompilerats för att köras som emulerad Intel-kod via Rosetta 2 visas istället processortypen som Intel i aktivitetsövervakaren, trots att koden körs på en Arm64-processor.

Apple_Arm64-21.jpg
Apple_Arm64-22.jpg
Apple_Arm64-23.jpg
Apple_Arm64-24.jpg

Slutligen lämnar Apple också tips om hur kod bäst skrivs för optimal asymmetrisk exekvering på bolagets flerkärniga Arm64-processorer. Inga detaljer anges om hur många dessa är, men typerna av kärnor utgörs av högpresterande (Performance, P) och energieffektiva (Efficient, E). Alla dessa kan vara aktiva samtidigt för parallell exekvering.

Vid prestandaanalys i Xcode-verktyget Instruments markeras de olika typerna av kärnor med ovanstående etiketter, vilket låter utvecklaren se hur belastningen fördelas över processorns olika kärntyper. Processorn i kombination med Mac OS sköter fördelningen mellan kärnorna dynamiskt, och Apple avråder därför utvecklare att manuellt styra hanteringen av trådar och kösystem för dessa.

Videogenomgången visar också exempel på hur utökningar i Mac OS (eng. extensions) kan och bör portas från Intel till ARM. På Apples utvecklardokumentation finns en sektion för "Apple Silicon" som innehåller tips och råd för utvecklare som vill porta applikationer till bolagets Arm64-processorer.

Läs mer från Apple WWDC 2020: