Ne vidim više upotrabljivost OC-a bilo gde. Čipovi su prilično dobro testirani i proizvođači sve tačnije znaju da odrede gornu granicu čipa. Mnogo puta mi se desilo da prilikom OC-a naletim na skrivene felere i vrlo netipične sledove instrukcija na kojima takav CPU pada iako je pre toga prošao kroz sve "diagnostičke" programe, memtest masiranja itd itd.
Onda nema ni upotrebljivosti od kupovine bržeg procesora. OC. za svaki dan ima i te kako smisla. Mislim da mešaš babe i žabe. Optimizacija koda naravno da je dobro došla, ali imaš stvari na koje ne možeš da utičeš. Npr. koristiš aplikaciju koja ima zatvoren kod i kako misliš da dobiješ 30% na brzini renderovanja bez oc.-a?
Što se tiče verifikacije overkloka, tu postoje razna rešenja i to uglavnom veoma dobro radi ako znaš šta radiš. Npr. uzmi jedan FX8120 koji radi na 3.1 GHz i klokni ga na 4.4 GHz i ubrzanje će biti vidno u svakoj računski zahtevnoj operaciji. Pri tom se podrazumeva da imaš adekvatno hlađenje i adekvatnu ploču.
Pored toga, tada potrošnja energije strmo raste a efekt je vrlo ograničen. U praksi mi se tu uvek daleko više isplatilo masiranje i optimizovanje koda. Između ostalog i zbog toga što takav kod daje rezultate i na svim ostalim a navijanje samo na jednoj mašini.
Ti onda i optimizuj i overklokuj.

Eksponencijalni rast potrošnje dolazi sa dizanjem napona.
Pa da je jednostavno, to bi radila moja baba. Inače, sam dekoderski blok i broj ekekucijskih jedinica ne bi trebalo da previše ( ako išta) utiče na dužinu pipelinea. BD je duži, pošto je svesno rađen u tom smeru- optimizovan je ka všim taktovima. Na kraju krajeva, ceo njegov modul je tamo negde oko starog corea ( pa i AMD kaže da ga modul košta 11% više površine od starog K10 corea IIRC). A i ta površina nije bogzna šta. Daleko najveći deo površine BD odnose razni keševi a ne logika.
Broj izvršnih jedinica i broj dekodera ima veze sa širinom, a ne sa dužinom, ali nisam o tome pričao nego o "rastezanju" FPU-a na dva modula....t.j. o tome si ti pričao ako se dobro sećam.

Elem, dužina pipelinea ima veze sa time koliko si "rastegao" integer blokova i threadova na jedan FPU. Oba core-a u modulu, t.j. integer bloka ne hendluju istovremeno FPU operacije, već rade naizmenično. Kada dve FPU operacije iz dva zasebna threada dođu u FP load queue, onda se izvršavaju na FPU jedinici OoO (out of order). Dakle, FPU pipeline se produžava za bar jedno stanje zbog kako ti kažeš "rastezanja".

Što se tiče površine, takođe se ne bih složio sa tobom. Modul bez L2 cache-a je veličine ~18mm2, dok je K10 core bez cache-a konkretno Husky u 32nm K12 površine
~9.69mm2. Takođe i broj tranzistora je dvostruko veći. To o čemu ti pričaš je koliko površine zauzima dodatni integer ALU klaster, ali si zaboravio na širi front end, na unapređen branch predictor, "deblji" FPU i još mnogo toga što je potrebno da naguraš u modul da bi se to ponašalo kao dva "old school" jezgra.
Šta ti znači "retko kad" ? U smislu "na malo mesta u programu" ili u smislu "mali procenat vremena" ? Prvo mi se ne čini relevantno. Kod je puno puta optimizovan na onim mestima gde se daleko najčešće izvršava. Pogledaj recimo kod u linux jezgri za izračunavanje sindroma paritete RAID-6. Stvar prži sa gasom do daske. Radi se o malj petlji ali ona odlučuje o RAID-6 performansama.
Ne znam koliko si se zezao sa kojekakvim profajlerima, ali tu možeš lepo da vidiš kako se ponaša kod i koliki IPC ima na određenom procesoru na kojem radiš.
Koliko znam, paritet se računa pomoću XOR operacija, a postoji nekolicina algoritama za računanje RAID6 pariteta koji staju u malu petlju. BD modul može da izvrši 2 XOR operacije po int. bloku, dakle ukupno 4, čime si iskoristio do kraja decoding bandwidth za 4 ALU operacije. IPC možda može da dogura do 2 po threadu ukoliko nema previše brljanja sa memorijom. Međutim ako koristiš SIMD, imaš PXOR operaciju koja radi sa pakovanim vektorom dužine 128-bita, u koji možeš da smestiš npr. po dve 64-bitne XOR operacije. Kako BD FPU ima 2 MAL jedinice, pipe2 i pipe3 koje rade sa pakovanim integerima i bitwise operacije, dve SIMD instrukcije se dekodiraju kao 2 instrukcije i ostaje dekoding bandwidth-a za još dve ALU/mem operacije za oba threada.
Da CPU ima neki slot više u SSE jedinici, stvar bi ga koristila i to b se jasno videlo u performansama. Da SSE unit ume da piči samostalno, stvar bi radila kalkulacije kako u klasičnom CPU-u tako i u SSE delu.
Nisam baš shvatio šta si ovime hteo da kažeš? CPU može da ima pristup celoj FPU jedinici koja ima 2x128bit FP, tj. FMA i 2x128bit INT SIMD tj. MMX. Dakle, FPU ima četiri pipelinea za oba threada ili za jedan thread. Komande koje izdaje ALU klaster idu celoj FPU jedinici i učitavaju se u FP load buffer.
Podaci se učitavaju preko L1D cache-a i prosledjuju se FPU jedinici. Svaki ALU klaster ima svoj data keš koji ima 2x128-bit load, ima dva porta za čitanje i jedan za pisanje. Dakle, u dva threada je moguće učitati 4 128 bitna podatka iz dva L1d cachea. Što se tiče čitanja podataka BD nije problematičan. Problematičan je fetch bandwidth od 2x16b koji dolazi sa instrucijske strane. Jednostavno gledano uzmi jednu 128-bitnu FMA instrukciju i još jednu ALU po threadu, i povućićeš vrlo blizu 16 bajtova. Ako instrukcije nisu poravnate, t.j. ako imaju "unaligned" pristup, najeb'o si sa performansama. Inače ovo je jedna od jačih strana Core arhitekture, rad sa "unaligned" operacijama.
I BTW ta mantra 2-3 instrukcije paralelizma ne važi tamo gde se snaga novih CPUa najviše reklamira - SSE/AVX jedinice. Te praktički uvek masiraju podatke u prilično tight loopovima a onda se rezultati koriste dalje. Već par puta sam gnjavio AMD zašto ne izvedu eksekuciju tih jedinica samostalno tako da:
- naredbe za njih ne guše zajednički instrukcijski dekoder
- da stvar ima mali bafer sa predekodiranim instrukcijama
- ima uslovne instrukcije.
- ima neki mali fleg registar ( "počni", "gotov sam" itd) za brzu komunikaciju sa CPU
Kao što rekoh već, dekoder nije problem, broj dekodera predstavlja širinu autoputa, a fetch bandwidth predstavlja brzinu autoputa i to može da bude problem. Npr. AMD K10 je dobio 15% na integer performansama samo zahvaljujući 32bajtnom fetch-u u odnosu na 16bajtni kod K8.
Kod AMD procesora tight loop-ovi se izvršavaju ponavljajući kod iz L1 Instrukcijskog keša. Ide L1-I -> fetch -> decode -> execute -> retire i tako iznova milijardu puta. Da imaš trace cache ili uOp cache to bi izgledalo ovako: 1. put L1-I ->fetch -> decode -> trace cache -> execute -> retire, a zatim: trace cache -> execute -> retire, dok bi front end (L1-I, fetch, decode) bio slobodan komplet za drugi thread ili bi štedeo energiju jer ne bi radio.
Bafer sa predekodiranim instrukcijama se zove uOp cache kod Sandy Bridge i Ivy Bridge-a. Nehalem i Core 2 koriste LSD (Loop Stream Buffer), s tim što Nhm ima veći LSD.
Kod SSE/AVX te načelno ne zanima baš tačno šta se u jedinic dešava iz takta u takt. To je više teška artiljerija za carpet bombing nego precizan instrument. Kada bi mgao da startuješ "loop execute mode", ti bi mogao da radiš svoje dok SSE gruva i da svake toliko proveriš je li završila. Na žalost još nije tako ali sve upućuje na to, da če u sledećim generacijama APU pixel shaderi igrati baš tu ulogu.
Zapravo ne bi mogao, jer moraš SIMD jedinice da "hraniš" sa ogromnom količinom podataka. Kao što sam već rekao imaš 2x128-bit load po ALU bloku. Odatle se pune FP registri u FPU jedinici. Ako koristiš FMA imaš 2 128 bitna loada za podatke, 128-bit za FADD i 128-bit za FMUL i imaš jedan upis kao rezultat operacije. To može u jednom kloku. 256-bitna FMA4 operacija po threadu će ići u dva ciklusa, donjih 128+128 prvo, pa onda gornjih 128+128b i upis iz dva dela. Svakako je brži kod gde imaš dva threada sa sve 128-bitne FMA4 operacije nego sa jednim threadom i jednom 256-bitnom FMA4 koja se "lomi" u dva ciklusa. Prema AMD optimisation manualu savetuje se korišćenje 2x128-bitnih AVX umesto 1x256. Ovde je usko grlo i FPU jedinica koja može da izvrši odjednom samo jednu 256b FP operaciju.
Teoretski gledano, BD može da izvrši 8x128-bit FMA4, što daje 32 DP FLOPS-a, odnosno 4x256-bit AVX, što je 16 DP FLOPS-a po ciklusu. Takođe može da se izvrši i 4x256b FMA4 u svakom drugom ciklusu, što je efektivno 2x256b FMA4 t.j. 16 DP FLOPS-a. Dakle, teoretski FP throghput je 32 DP FLOPS-a sa 128-bit FMA4, što je isto kao i kod Sandy Bridge-a sa 4 jezgra i 256-bit AVX.
Pa dobro, sad ti ako želš da ideš u ekstreme, možeš praktično svaku instrukciju da razvučeš na do 15 bajtova prefixima itd. U nekom solidnom optimizovanom kodu možeš da upenališ stvari tako, da koristiš kratke instrukcije. Tada bi ti mogućnost jačeg dekodera vrlo dobro došla. A još ako ne bi bio "zakrčen" SSE instrukcijama, toliko bolje.
Shvati da korist od SIMD instrukcija je vеća nego što je penal pri dekodiranju. Pored toga SIMD kod je "ortogonalniji" od klasičnog x86 koda, tako da problem sa "unaligned" pristupom je lakše rešiv.
I da...teško da ćeš da naguraš 15 bajtova po instrukciji sa prefiksima. Prefix može biti od 0-4 bajtova, t.j. 4 prefiksa od po jedan bajt. Opkod je 3 bajta, displacement adresa 0-4 bajta, direktna adresa 0-4 bajta, ako radiš direktno sa registrima nema adresacije.
Instrukcija može biti i 15 bajtova ako je "double op" dekodirana. Ne dekodiraju se baš sve instrukcije na jednu MOP - makrooperaciju. Naročito ne ove 256-bitne AVX.
256-bitna AVX instrukcija bez prefiksa ima 11 bajtova, ali se kod AMD-a dekodira kao dve makrooperacije. Zahvaljujući tome što AMD ima kompleksni dekoder svaki dekoder može da dekodira do dve MOP (makrooperacije). Dakle, 256-bitna AVX instrukcija se dekodira kroz jedan dekoder, ali u pipelineu zauzme 2 slota, t.j. izvršava se kao dve makroinstrukcije. Kad dekodiraš jednu 256-bitnu instrukciju, nisi ni blizu zagušio širinu dekodinga, već si zagušio dobrim delom fetch. Srećom pa ostaje još jedan "prozor" od 16-bajtova za drugi thread.
Pa to je već korišteno na P4 AFAIK. Ali kako izgleda, nije bez mana. Meni je svejedno - dekoderi, keširanje predekodiranog koda ili nešto treće, samo da dekoding ne bude usko grlo.
P4 je ekstrem, zato što je imao samo JEDAN dekoder i to je premalo. Naročito ako dođe do misspredict-a. Zapravo P4 nema klasičan i-cache, nego ima trace cache koji sadrži BP - branch predictor. Kada BP ne predvidi dobro grananje, sve ide iznova, a sa 20-30 stanja dugim pipelineom imaš ozbiljan penal.
Razlika između 4 dekodera i jednog i klasičnog instrukcijskog keša u kombinaciji sa uOp cacheom i trace cachea bez I cachea je ogromna.
Ti problemi mene lično ne pogađaju i ne zanimaju. Radim sa otvorenim kodom između ostalog i iz tog razloga. Ako mi se nešto ne sviđa, otvorim source, pogledam i promenim. Keš može da bude problem ali ako može da opsluži SSE stream, trebalo bi da može i CPU jedinicu.
Iskreno ne znam koliko si iskusan programer da možeš da optimizuješ kod toliko da izbegavaš tzv. data dependencies. Ne znam koliko si se bavio vektorizacijom koda, ali svakako je pametnije vektorizovati i multithreadovati ono za šta ima smisla to raditi.
Što se tiče keša, L1 ima znatno veći bandwith od L2, dok ovaj ima veći banwidth i nižu latenciju od L3....itd... Npr. može petlja da ima kratak kod, to staje u I cache, ali je problem odakle vučeš podatke i kako radiš sa njima. Naročit problem je korišćenje sistemskih C/C++ stdlib biblioteka za rad sa memorijom. Ako stvarno hoćeš da to radi brzo, onda moraš da napišeš svoj memory manager za aplikaciju.