windows - Er ikke alle processorer oprettet lige?

Indlæg af Hanne Mølgaard Plasc

Problem



Min bærbare computer har 4 logiske processorer (to fysiske); logiske CPU'er 1 og 2 kort til kerne 1 og logiske CPU'er 3 og 4 kort til kerne 2 (verificeret med GetLogicalProcessorInformation()).


Jeg kørte et multithreadet matrix multiplikationsprogram på min computer med to tråde. Første gang brugte jeg SetProcessAffinityMask(hProcess, 0x5) (som betyder logiske processorer 1 og 3), mens anden gang jeg brugte SetProcessAffinityMask(hProcess, 0xA) (logiske processorer 2 og 4).


Det viste sig, at den første version var omkring dobbelt så hurtig som den anden version, som om jeg aldrig multithreaded den anden version alligevel.


Har nogen nogen gæt om hvorfor dette kan ske?





Mål:



  • Tilsluttet (fuld CPU):



    • Affinity mask: 0x3 (0011b), 9 gflop/s

    • Affinity mask: 0x5 (0101b), 17 gflop/s

    • Affinity mask: 0x6 (0110b), 17 gflop/s

    • Affinity mask: 0x9 (1001b), 9 gflop/s

    • Affinity mask: 0xA (1010b), 9 gflop/s

    • Affinity maske: 0xC (1100b), 9 gflop/s


  • På batteriet (nedklækket):



    • Affinity mask: 0x3 (0011b), 5 gflop/s

    • Affinity mask: 0x5 (0101b), 10 gflop/s

    • Affinity mask: 0x6 (0110b), 10 gflop/s

    • Affinity mask: 0x9 (1001b), 5 gflop/s

    • Affinity maske: 0xA (1010b), 2 gflop/s
      (-> Meget interessant, hvorfor halv hastighed når du er i batteriet, men normal hastighed på AC ?! Denne varierer meget mellem 1,5-2,5 gflop/s, i modsætning til de andre.)

    • Affinity maske: 0xC (1100b), 5 gflop/s




betyder det, at den fjerde logiske CPU ikke gør noget (!)? (Alt med masken til det fjerde CPU sæt er langsom.)





Opdatering:


Jeg har lige sporet det samme på High Performance-profilen på batterier . Resultaterne er inkonsekvente: Denne gang fik jeg 2x speedup for maskerne 5, 6 og 10, men der var ingen fart på masken 12. Jeg vil forsøge at køre testen igen på vekselstrøm, men i sidste ende virker det som dette Resultatet er en kombination af strømstyring, Turbo Boost, planlægning af inkonsekvenser osv., og det er sværere at måle end jeg tidligere troede. :(

Bedste reference


Det ville være godt at vide, hvilken fysisk CPU dette er, men jeg antager fra din formulering om logiske processorer, at der er 1 fysisk stikkontakt, 2 CPU-kerner og hyperthreadning, der giver dig 4 logiske processorer.


Det korte svar er for denne komplicerede definition af 'processor' nej, ikke alle processorer er skabt ens. Hjertehårede logiske kerner deler udførelsesressourcer, og hvis deres påstand om disse ressourcer vinder de ikke hurtigt som separate fysiske kerner. Denne deling kan foregå på forskellige niveauer for både hyperthreading og multicore-processorer (ALU, eksekveringsressourcer, cache på forskellige niveauer osv.), Men i vid udstrækning vil fysiske kerner i samme stik ikke blive påvirket meget af, hvad den anden kerne ( s) gør/gør, og logiske kerner implementeret af hyperthreading vil blive meget påvirket af, hvad deres hypertwin gør.


En anden forskel mellem forskellige CPU'er: Som sagt, kan dit operativsystem behandle de fleste hardwareafbrydelser på en enkelt CPU, hvilket betyder, at CPU'en vil synes langsommere til andre formål, men jeg er overrasket over, om afbrydelsesbelastningen er nok til at påvirke ydeevnen hvor som helst nær så meget.


De resultater, du har - på processorerne A og B (der er bevidst tvetydigt om hvilke 2 processorer de er) får du dobbelt udførelse af A alene, men på processorer A og C får du omtrent samme ydeevne som A alene - sikker lyd ligesom hyperthreading er forskellen, hvor A og C er hypertwins i samme fysiske kerne, og B er i den anden fysiske kerne. Du sagde, at GetLogicalProcessorInformation () hævder ellers, men det er ikke uhørt for BIOS-tabellerne, som det afhænger af at have fejl.


Jeg ville køre Task Manager, holde øje med belastninger på hver CPU, før du kører din test for at få en ide om, hvor meget andet der foregår, og hvor Windows planlægger det, så kør testen igen et par gange til forskellige kombinationer af CPU affinitet, og se om du kan bekræfte eller benægte denne teori.

Andre referencer 1


SetProcessAffinityMask () garanterer ikke, at du vil have en tråd pr. Kerne; kun at trådene du har, vil løbe på de kerner, du har tilladt.


Måske er OS planlægning anderledes.


Jeg er også overrasket over, at 1 og 2 er på kernen 1. Normalt indgår logiske processornumre over fysiske kerner for at give en iboende belastningsbalancering. Jeg forventer, at 1 og 3 skal være på kernen 1, 2 og 4 for at være kernen 2.

Andre referencer 2


Nej, ikke alle kerner er ens. Kun en er startkernen. Desuden er i mange tilfælde alle IRQ'er (eller i det mindste IRQ'er fra et flertal af enhederne) rettet mod en enkelt kerne.





Mere vigtigt for din observerede adfærd er ikke alle sæt af kerner er ens. I en NUMA-hukommelsesarkitektur (som har været relativt almindelig i x86 siden Intel Hyperthreading og AMD Opteron), er der en ideel gruppe processorer, der effektivt kan få adgang til en bestemt hukommelsesområde, og alle andre processorer betaler en betydelig straf for at få adgang det interval.


Med Hyperthreading er det ikke hovedsystemhukommelsen, der er forbundet ikke-ensartet, men L1 og L2 cache. Hvis din proces migreres mellem de to virtuelle processorer, der er knyttet til den samme fysiske kerne, forbliver cachen gyldig. Men hvis det migrerer til den anden fysiske kerne, skal cachelagrede data kopieres og ejerskab overføres til den anden cache. For nogle arbejdsbelastninger kan dette gøre en stor forskel.

Andre referencer 3


Har du tjekket returkoden fra SetProcessAffinityMask for at se, om der opstod en fejl? Hvis opkaldet fejler, kan du blive fast på en logisk processor. Ifølge dokumentationen kan du kun bruge de bits, der er angivet i resultatet af GetProcessAffinityMask. [10]


Du siger, at du har prøvet masker af 0x5, 0xA og 0x9. Jeg er nysgerrig efter at se resultaterne med 0x3.