Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational...

53
Scuola Politecnica e delle Scienze di Base Corso di Laurea in Ingegneria Informatica Elaborato finale in Calcolatori Elettronici I Tecniche e strumenti di testing per processori superscalari Anno Accademico 2015-2016 Candidato: Luca Pirozzi matr. N46001969

Transcript of Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational...

Page 1: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

Scuola Politecnica e delle Scienze di Base Corso di Laurea in Ingegneria Informatica

Elaborato finale in Calcolatori Elettronici I

Tecniche e strumenti di testing per processori superscalari

Anno Accademico 2015-2016

Candidato: Luca Pirozzi matr. N46001969

Page 2: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

Ai miei genitori e a mio fratello per l’insostituibile supporto. A chi non c’è più ma continua ad esserci nelle nostre azioni.

Page 3: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

Indice

Indice .................................................................................................................................................. III Capitolo 1: I Sistemi Safety Critical .................................................................................................... 5

1.1 Regimi di sicurezza ............................................................................................................... 6 1.2 Caratteristiche e applicazioni ................................................................................................ 7

1.3 Standard nei trasporti............................................................................................................. 7 1.4 CENELEC EN 50126 ............................................................................................................ 8 1.5 CENELEC EN 50128 ............................................................................................................ 9 1.6 CENELEC EN 50129 .......................................................................................................... 10

1.7 CENELEC EN 50155 .......................................................................................................... 11 1.8 CENELEC EN 50159 .......................................................................................................... 11

Capitolo 2: Testing dei processori ..................................................................................................... 13 2.1 Scelta del processore per un sistema critico ........................................................................ 14 2.2 Evoluzione delle metodologie di testing ............................................................................. 15 2.3 Testing software .................................................................................................................. 16 2.4 Self-testing software ............................................................................................................ 17

2.5 Pattern di Testing................................................................................................................. 22 Capitolo 3: Intel® Processor Diagnostic Tool ................................................................................... 23

3.1 Programmi di test ................................................................................................................ 23 3.2 Analisi dei codici sorgenti ................................................................................................... 25 3.2.1 Genuine Intel ................................................................................................................... 25

3.2.2 Temperature ..................................................................................................................... 27 3.2.3 Brand String ..................................................................................................................... 28

3.2.4 CPU Frequency ................................................................................................................ 29 3.2.5 Floating Point................................................................................................................... 31

3.2.6 Prime number generation ................................................................................................. 31 3.2.7 Cache ............................................................................................................................... 33 3.2.8 MMXSSE ........................................................................................................................ 34 3.2.9 AVX ................................................................................................................................. 34 3.2.10 IMC .................................................................................................................................. 35

3.2.11 PCH.................................................................................................................................. 36 3.2.12 IGD .................................................................................................................................. 37 3.2.13 GFX ................................................................................................................................. 38 3.2.14 CPU Load ........................................................................................................................ 38

Conclusioni ........................................................................................................................................ 40

4.1 Difetti di Intel® Processor Diagnostic Tool ........................................................................ 40 4.2 Elementi di resistenza a un testing efficace ......................................................................... 46

4.3 Soluzioni e possibili sviluppi futuri..................................................................................... 48

Bibliografia ........................................................................................................................................ 51

Page 4: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo
Page 5: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

5

Capitolo 1: I Sistemi Safety Critical

Un sistema informatico si definisce critico se un suo fallimento comporta perdite. In base

alle conseguenze di tale fallimento, i sistemi critici vengono così classificati [1]:

• Business - critical: un fallimento può portare a gravi perdite economiche e notevoli

disservizi.

Esempi: sistemi bancari, grandi siti di e-commerce.

• Security - critical: un fallimento può portare alla perdita di informazioni sensibili.

Esempi: sistemi ospedalieri e amministrativi.

• Mission - critical: il fallimento non permette il corretto completamento degli obiettivi del

sistema (sistemi goal – driven).

Esempio: sistema di navigazione di una sonda spaziale.

• Safety - critical: un fallimento può portare a infortuni gravi o alla morte, e può causare

seri danni all’ambiente.

Esempi: sistema di controllo di una centrale nucleare, sistema di controllo dei treni.

Tra i vari tipi di sistemi critici elencati, la tipologia con i vincoli più stringenti è sicuramente

quella dei safety-critical: per questo motivo ne condurremo un’analisi dettagliata al fine di

rilevarne le proprietà principali.

Page 6: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

6

1.1 Regimi di sicurezza

Sono definiti diversi regimi di sicurezza per i sistemi safety-critical [2]:

Fail-operational systems: il sistema deve continuare ad operare anche se la

componente di controllo fallisce (ascensori, termostati, sicurezza nucleare passiva).

Fail-safe systems: nel momento in cui sono impossibilitati ad operare, sono

comunque sicuri. Il caso tipico è quello dei sistemi medici che quando cessano di

funzionare allertano il personale di competenza, e facendo sì che l’intervallo di non

operatività sia sufficiente per la sicurezza del paziente. Tale sistema non potrà

operare in maniera non controllata e quindi pericolosa.

Fail-secure systems: sono sicuri anche quando falliscono. Questa proprietà è tipica

delle porte elettroniche: mentre una di tipo fail-safe potrebbe ancora essere aperta,

una di tipo fail-secure si chiuderebbe automaticamente in caso di fallimento, in

modo da mantenere un’area sicura.

Fail-passive systems: continuano ad operare anche in seguito ad un fallimento del

sistema di controllo. Un esempio è l’autopilota: anche se dovesse fallire il pilota

potrà comunque guidare il velivolo

Fault-tolerant systems: evitano il malfunzionamento del sistema anche in caso di

fallimenti interni al sistema. Questo è il caso dei sistemi di controllo del reattore, in

quanto gli elementi del controllo sono tipicamente distribuiti in modalità hot-spare,

ovvero ve ne sono di più sulla stessa area, in modo che anche in caso di fallimenti,

un altro sistema equivalente possa funzionare al posto del sistema in fallimento.

Page 7: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

7

1.2 Caratteristiche e applicazioni

L’ingegneria del software dei sistemi safety-critical è particolarmente complessa:

perseguire i canonici fattori di qualità, come la correttezza o la robustezza risulta essere ben

più difficile, a causa del margine di errore sostanzialmente nullo dei loro domini applicativi.

Affinché possa essere raggiunta la più alta affidabilità possibile, alcuni aspetti della

software engineering diventano particolarmente importanti:

• Controllo del processo ingegneristico e della sua componente gestionale

• Scelta di tools di sviluppo adeguati, e redazione accurata dei casi di test

• Uso degli standard del dominio

Tali sistemi hanno trovato applicazione in moltissimi settori, come:

• Medico (defibrillatori, macchine per la dialisi, sistemi di respirazione artificiale)

• Nucleare (sistemi di controllo del reattore)

• Automotive (airbag, sistemi di frenata assistita, drive by wire)

• Ferroviario (gestione traffico dei treni, sistemi di frenata automatica)

• Aviazione (sistemi fly by wire, controllo motore, pianificazione volo)

• Spaziale (sistemi di supporto vitale)

• Infrastrutture (salvavita, sensori antincendio, telecomunicazioni)

• Ricreativo (controllo montagne russe)

1.3 Standard nei trasporti

Come abbiamo visto, uno dei settori in cui l’utilizzo dei sistemi safety-critical è più

fruttuoso è quello dei trasporti.

Per garantire la massima sicurezza, sono stati definiti standard per tali sistemi per i diversi

settori; i più famosi sono:

• Per l’aviazione il DO-178B [3], introdotto il 1° settembre 1992, rappresenta un

insieme di linee guida, che anche se non è definito come uno standard vero e proprio, lo è

de facto.

• Per il trasporto ferroviario gli standard CENELEC EN (50126, 50128, 50129,

50155, 50159 [4]). Tali standard, che trovano larga applicazione in Europa, ma che si

Page 8: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

8

stanno diffondendo sempre di più in altri paesi (sono stati definiti accordi con Stati Uniti e

Giappone). A partire da questi, la IEC (International Electrotechnical Commission) ha

definito delle normative equivalenti (62278, 62279, 62425,62280).

Tratteremo quindi gli standard definiti nell’ambito dei trasporti ferroviari, studiandone i

principali aspetti.

1.4 CENELEC EN 50126

Lo standard CENELEC 50126 si basa sui fattori di qualità indicati con l’acronimo RAMS

[5] (Reliability, Availability, Operation & Maintenance, Safety). Tale standard definisce

un processo, in base al ciclo di vita e al compito del software, per perseguire i fattori RAMS

e soluzioni efficienti nel caso i fattori siano in conflitto fra loro. Il processo descritto da tale

standard è sistematico e sono definiti metodi per verificare tali fattori di qualità. Tale

processo è sostanzialmente una rivisitazione del modello a V utilizzato comunemente

nell’ingegneria del software, anche se può variare in base alla complessità del sistema da

realizzare. Tale standard è applicabile a tutti i nuovi sistemi, sottosistemi e hardware

specificamente progettati per il settore ferroviario, ma è applicabile in alcune parti anche

50126

50126

Sistema Complessivo

Treno Sottosistema di segnalazione

Strumentazione

Strumentazione

Hardware Hardware Software Software

50155 50128

50129

50159

Page 9: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

9

per sistemi preesistenti. Lo standard permette di valutare i sistemi ferroviari attraverso

diversi parametri, come il tasso di fallimento, tempo medio di operatività, tempo medio di

indisponibilità, tempo medio di fallimento, distanza media di fallimento, tempo medio fra

due fallimenti, distanza media tra due fallimenti [6] . Non definisce alcuni elementi [5],

come il processo di approvazione dell’autorità ferroviaria (fornisce infatti metodi interni

all’azienda per valutare il raggiungimento dei parametri RAMS), che può in questo modo

definirne liberamente uno proprio, in base ad altre normative nazionali o comunitarie, non

specifica soluzioni per una specifica applicazione, potendo essere applicata a diversi tipi di

sistemi ferroviari, né definisce come perseguire il parametro di security: infatti mentre la

safety è un parametro che permette di valutare la protezione da incidenti casuali, la security

riguarda attacchi intenzionali al sistema, come tentativi di hacking dei dispositivi.

1.5 CENELEC EN 50128

Lo standard CENELEC 50128 può essere applicato unicamente al software e

all’interazione software – sistema [7]. Sono tipicamente interessati dallo standard la

programmazione delle applicazioni, i sistemi operativi, i tools di supporto e i firmware.

Anche in questo caso il ciclo di vita è riconducibile al modello a V. I linguaggi di

programmazione sono catalogati in base a diversi livelli di SIL (safety integrity level), che

sono stati definiti con lo standard IEC 61508: i livelli vanno da SIL-SW 0 (minore safety)

a SIL-SW 4 (maggiore safety), anche se per tutto ciò che è safety-related il livello base è

SIL SW 1, mentre per i safety-critical è SIL SW 3. Il linguaggio di programmazione

consigliato è l’ADA, per diversi motivi [8]: è strutturato, staticamente e fortemente

tipizzato, imperativo, può agire sia a basso livello che ad alto livello, è orientato agli oggetti:

tipicamente solo un sottoinsieme del linguaggio viene però utilizzato, in modo da garantire

il più possibile il parametro di safety del sistema. Vengono definiti inoltre standard per il

codice e una guida per lo stile di programmazione. Tra le varie caratteristiche che un buon

codice dovrebbe avere troviamo [8]: l’assenza di oggetti e di variabili dinamiche, uso

limitato dei puntatori e della ricorsione, programmazione strutturata (one entry – one exit

per funzioni e sottoprogrammi), information hiding/incapsulamento, limite al numero dei

Page 10: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

10

parametri, uso limitato delle variabili globali, la struttura modulare, che da SIL SW 1 in poi

risulta obbligatoria. CENELEC 50128 tratta anche altri linguaggi di programmazione e li

classifica [8]: risultati soddisfacenti sono stati ottenuti anche dal MODULA-2 e dal

PASCAL, mentre possono essere utilizzati anche il Fortran 77, JAVA, C# e un

sottoinsieme del C/C++ con standard di codifica, anche se con garanzie di safety minori.

Viene scartato l’utilizzo del C/C++ standard se non nel caso SIL SW 0.

1.6 CENELEC EN 50129

Lo standard CENELEC 50129 si applica a tutti i sistemi, sottosistemi e hardware per la

comunicazione, la segnalazione e l’elaborazione nell’ambito della segnalazione ferroviaria

per garantirne la safety [9]. Lo standard si applica a tutto il ciclo di vita del prodotto: analisi

e specifica, progettazione, realizzazione, installazione, testing, manutenzione ed

evoluzione, sia di un sistema di segnalazione completo, sia dei suoi sottosistemi (questo è

particolarmente utile quando si devono integrare sottosistemi nuovi in un sistema di

segnalazione già esistente) [9]. Tale standard categorizza i dispositivi in base ai livelli di

SIL, allo stesso modo del già trattato standard 50128.

Così come il CENELEC 50126 può essere applicato a tutti i sistemi e sottosistemi nuovi,

ed in misura limitata a quelli già esistenti, attraverso modifiche ed estensioni. Può essere

applicato a quei sistemi specificamente pensati per operare in questo dominio, ma anche,

fin quanto è ragionevolmente possibile, a sistemi general purpose (ad esempio alimentatori

o modem) o dispositivi di altri domini industriali utilizzati nel sistema di segnalazione: deve

essere dimostrato almeno che un sistema general purpose utilizzato nella segnalazione

ferroviaria o non viene utilizzato in alcuna attività safety-related oppure che risulta essere

sicuro in tutte le attività safety-related in cui è coinvolto . Lo standard tratta della safety del

Sistema di segnalazione, ma non della sicurezza del personale addetto, che viene tutelata

da altre normative [9]. Tipicamente il CENELEC EN 50129 non può essere utilizzato da

solo, se non in un numero ristretto di casi, in quanto gran parte dei concetti su cui si basa

sono contenuti nello standard 50126: ad esempio, riguardo al ciclo di vita del software, in

EN 50129 viene considerato implicito, in quanto contenuto già in EN 50126, così come la

Page 11: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

11

valutazione del rischio viene solo accennata.

1.7 CENELEC EN 50155

Lo standard CENELEC EN 50155 si applica [10] a tutti i dispositivi elettronici per il

controllo, alimentazione e protezione installati su un veicolo ferroviario, collegati o alla

batteria del veicolo o ad un alimentatore a basso voltaggio eventualmente collegato alla

linea di contatto, ma non ai dispositivi elettronici di potenza (convertitori, raddrizzatori,

invertitori). Lo standard definisce come dispositivo elettronico qualsiasi sistema composto

essenzialmente da dispositivi a semiconduttore e componenti a loro associati,

principalmente montati su un circuito stampato [10]. Definisce le condizioni di

funzionamento (intervallo di temperatura di funzionamento, umidità tollerabile, resistenza

agli urti e alle vibrazioni), che devono essere rispettate, nonché regole per il progetto, la

realizzazione ed il testing, requisiti hardware e software per la realizzazione di dispositivi

affidabili ed efficienti. Tale standard può essere complementato da altri, nel momento in

cui se ne avverta la necessità. Eventuali requisiti speciali necessari vanno definiti

concordemente allo standard EN 50126. Dal punto di vista del software, il livello di

integrità software deve essere definiti in base ai rischi connessi all’applicazione, seguendo

i dettami di EN 50128.

1.8 CENELEC EN 50159

Lo standard CENELEC EN 50159 si applica ai sistemi elettronici per la comunicazione in

applicazioni critiche, che fanno uso di modalità di trasmissione non necessariamente

progettati per tali scopi, sia nel caso che tali sistemi siano progettati seguendo tale standard

sia che non lo siano, persino nel caso in cui il dispositivo sia conosciuto solo parzialmente

[11]. Lo standard prevede che al sistema di trasmissione possano essere collegati sia

componenti critici che non. Vengono definiti i requisiti fondamentali per una

comunicazione sicura tra dispositivi critici, di solito implementata nella strumentazione

descritta da EN 50129 e progettata quindi secondo tale standard, è necessario far

riferimento a EN 50129 anche per quanto riguarda la gestione della qualità e della sicurezza.

Page 12: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

12

EN 50159 contempla la possibilità che i requisiti debbano essere rispettati anche da altri

dispositivi del sistema di comunicazione, a patto che si applichino le opportune misure per

rispettare i vincoli di sicurezza. Lo standard non specifica la struttura del sistema di

comunicazione, i dispositivi che vi sono connessi, soluzioni particolari (ad esempio per

l’interoperabilità), distinzione fra dati critici e non. Lo standard non può applicarsi a sistemi

già esistenti, ma può essere utilizzato per estensioni di sistemi, sottosistemi e

strumentazione che non sono stati progettati seguendo tali standard [12]. EN 50159 non

affronta gran parte delle problematiche di sicurezza informatica: sono affrontati solo casi

molto semplici ma non vengono trattati aspetti importanti come la confidenzialità delle

informazioni safety-critical e il sovraccarico del sistema di comunicazione [11]. Sono

definiti inoltre vincoli sul sistema di trasmissione [12]: deve essere considerato lo scenario

in cui vi sono solo accessi da parte del personale autorizzato, è definito e conosciuto il

numero massimo di partecipanti connessi, il mezzo trasmissivo è noto e fisso.

Page 13: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

13

Capitolo 2: Testing dei processori

I sistemi safety-critical sono tipicamente governati da micro-controllori, circuiti integrati

contenente processore, memoria e periferiche di input e di output. I moderni

microcontrollori possono essere dotati di funzionalità avanzate, come la possibilità di

connettersi ad Internet o di poter processare segnali (DSP), anche video. Come ben

sappiamo, in base al modello di Von Neumann, è il processore deputato ad eseguire tutte

le elaborazioni: possiamo dire che, complessivamente, il controllo vero e proprio viene

eseguito da un processore.

Componenti e interconnessioni di un processore formano la cosiddetta Register Transfert

(RT) level description [13], e sono sia di tipo funzionale (ALU, shifter dei registri, adder,

moltiplicatori), di memoria (registri, flags) che logici (bus, multiplexer).

Non tutti i componenti sono testabili facilmente: mentre alcuni possono essere direttamente

stimolati per avere una risposta, altri reagiscono a stimolazioni di altri componenti, e ciò li

rende difficilmente testabili, come ad esempio il registro di stato [13].

Considerando i danni che il fallimento di un sistema safety-critical può comportare, è

necessario che i processori siano conosciuti nella loro completezza e che ci assicuri, nel

limite della ragionevolezza, l’assenza di errori durante l’esecuzione delle istruzioni.

Tale questione diventa fondamentale quando si ha un cambio di architetture, come quella

che sta avvenendo con la terminazione della produzione delle schede integrate con

processore Intel Atom e l’inizio dell’utilizzo di microcontrollori con processore Intel i5.

Page 14: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

14

2.1 Scelta del processore per un sistema critico

Esistono diverse opzioni nella scelta del processore per un sistema critico [14], ognuna

delle quali ha punti a favore ed altri negativi.

Processori scalari: Molte aziende preferiscono utilizzare processori dalle caratteristiche

ben conosciute, sul mercato da decenni, di tipo scalare, ovvero che sono in grado di

processare un solo dato alla volta (SISD), come ad esempio il Motorola 68020 (aereo da

caccia Eurofighter Typhoon [15], treni TGV, sistema di segnalazione ferroviario TVM

[16]). La ridotta complessità, unita al fatto che la quasi totalità dei difetti, dopo decenni di

utilizzi, dovrebbero essere conosciuti, garantisce un livello di affidabilità tale da convincere

molte imprese ad utilizzarli.

Tuttavia un aspetto negativo è il termine della produzione di gran parte di tali processori,

che non sono più utilizzati per l’elettronica di consumo. Alcune compagnie hanno

acquistato quasi tutte le rimanenze [14], in modo da averne una scorta: si noti, però, come

un processore abbia una longevità massima di 30 anni, e il 68020 ha iniziato la sua

produzione nel 1984.

Processori ad hoc: Un altro tipo di soluzione è quella di costruire da sé il processore

necessario per il sistema critico. Una CPU progettata per un determinato ambiente di

esecuzione ha la certezza di essere ottimizzata in tal senso, e di implementare tutti e soli i

meccanismi necessari. Tuttavia una scelta di questo tipo è molto costosa, e non beneficia

dell’enorme mole di testing “implicito” condotto dagli utilizzatori di sistemi convenzionali,

risultato sotto questo aspetto paradossalmente meno affidabile, richiede lo sviluppo di tool

collaterali (compilatori) [14], e non tutte le aziende hanno il personale e il know-how

necessario per percorrere questa strada (o per farlo in tempi e costi sostenibili).

Processori superscalari: l’ultima possibilità è rappresentata dall’utilizzo di processori

recenti, di tipo superscalare (ovvero che sono in grado di processare più di un istruzione

per singolo colpo di clock, SIMD o MIMD in base al numero di core). Il vantaggio è

rappresentato dalle maggiori prestazioni di queste CPU e dal fatto che sono attualmente in

produzione anche per elettronica di consumo. Lo svantaggio è che sono notevolmente più

complessi, e che il testing utilizzato per i sistemi di consumo non può sempre essere

Page 15: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

15

utilizzato per i sistemi critici in quanto il primo si focalizza sull’average case e il secondo

sul worst case [14].

2.2 Evoluzione delle metodologie di testing

Parallelamente al rapido sviluppo dei processori, le tecniche di testing si sono evolute nel

tempo.

Inizialmente i processori venivano testati completamente in hardware, facendo sì che

l’intero instruction set, ossia l’insieme delle istruzioni che la CPU è in grado di eseguire,

venisse eseguito: ciò veniva fatto su tutti i registri: è chiaro che un test di questo tipo diviene

esponenzialmente più costoso al crescere della complessità del processore.

Altri elementi che rendono difficile, se non impossibile, l’applicazione di tali tecnica nella

maggior parte dei casi sono:

• Complessità delle CPU: dagli anni 80 in poi lo sviluppo dei transistori ha permesso la

produzione di circuiti a scala di integrazione molto grande (o very large scale

integration, VLSI). Tali circuiti, presenti anche nelle moderne CPU, sono caratterizzati

da un numero di transistori per area elevatissimo (ad esempio si è arrivati anche a 4,3

miliardi di transistori su uno stesso chip). Si capisce come dal solo punto di vista

strutturale i moderni processori siano molto complessi da testare.

• Le moderne CPU sono multicore: il processore delegherà l’esecuzione dell’istruzione

ad una qualsiasi delle unità di elaborazione. Anche se si volesse testare la stessa

istruzione su tutti i core, il non determinismo della scelta renderebbe particolarmente

costosa l’operazione.

• Meccanismi di pipelining delle istruzioni: mentre i processori di tipo scalare, la cui

produzione per il mercato di massa si è arrestata ormai decenni fa, sono in grado di

processare una sola istruzione per ciclo, e hanno quindi un comportamento sotto questo

punto di vista deterministico, i processori superscalari sono in grado di processare più

istruzioni alla volta: tale processo è non deterministico. Il pipelining, introducendo non

determinismo, rende molto più complesso il testing. Inoltre sono possibili errori dovuti

proprio al pipelining, nel caso questo non venga gestito correttamente.

Page 16: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

16

• La frequenza: le moderne CPU operano a frequenze dell’ordine del Gigahertz,

rendendo sempre più costoso lo sviluppo della strumentazione di testing (Automatic

Testing Equipment), che, secondo la Semiconductor Industry Association Roadmap già

nel 1997 [17] poteva raggiungere un costo di 20 milioni di dollari. Questo problema non

è aggirabile utilizzando dispositivi che operano a frequenze più basse perché possono

esserci difetti della CPU che si manifestano solo alle frequenze più elevate (at-speed

testing).

• Le metodologie di self-testing comportano una perdita di prestazioni: per alcuni

tipi di dispositivi (FPGA) e per CPU semplici è possibile delegare il testing ad una apposita

circuiteria, che, una volta attivata, permette al dispositivo di “testare se stesso” (BIST o

Built-in Self Testing), facendo uso di scan chains. Tale tecnica, tuttavia, richiede un

aumento di area del circuito e una conseguente degradazione delle prestazioni: per le CPU

complesse come quelle di oggi, tale tecnica risulta non essere fattibile.

• Necessità di mercato: il testing dei processori è un’attività costosa in termini di

tempo e di risorse. Se tale attività viene condotta in hardware, lo è particolarmente.

Considerando che un gran numero di processori viene immesso sul mercato per essere

utilizzati su normali computer, si tende a trovare un buon compromesso fra completezza

dei test e costi/time to market.

2.3 Testing software

Da tali problematiche sorge l’esigenza di rendere il testing dei processori meno costoso e

più veloce. Una soluzione pratica può essere quella di delegare tutto o parte del testing al

software. Questo è conveniente per l’intrinseca flessibilità del software, che può essere

riprogrammato facilmente e a basso costo; inoltre, al contrario dell’hardware, non richiede

una considerevole aggiunta di circuiteria tale da peggiorare i parametri di area e di ritardo

del processore. Inoltre nel caso di testing hardware di tipo built-in, le scan chains necessarie

vanno progettate insieme al circuito stesso, che risulta, già nel progetto, come un

compromesso tra sicurezza e prestazioni; di contro, il testing software può essere progettato

in un secondo tempo rispetto al processore, in modo che il progetto di quest’ultimo possa

Page 17: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

17

essere orientato maggiormente verso le prestazioni.

Tuttavia tipicamente le suite di test diffuse commercialmente sono di tipo funzionale, ma

non di tipo strutturale, e si limiteranno a determinare il funzionamento del processore

durante alcune operazioni ben definite (di solito istruzioni di un linguaggio di

programmazione, non vengono utilizzate direttamente le istruzioni del processore), senza

poter ad esempio individuare difetti strutturali dello stesso: ciò infatti richiede la

conoscenza della struttura del processore, ovvero componenti e relative interconnessioni,

che tipicamente non possono essere rese pubbliche per motivi commerciali (timore ad

esempio che un concorrente possa copiare le proprie soluzioni), nonché l’intero instruction

set della CPU.

Sebbene esistano tecniche di testing software diverse e con differenti gradi di astrazione

(dal linguaggio assembly fino a suite di test scritte in linguaggi orientati agli oggetti), in

generale è possibile individuare due fasi fondamentali:

• Codifica dei test: deciso il linguaggio di programmazione da usare (che può anche

essere ibrido, ovvero utilizzare sia il linguaggio assembly che un linguaggio a più alto

livello nello stesso programma) si procede alla stesura della suite di test.

• Esecuzione dei programmi di test e confronto col risultato atteso (oracolo): un altro

vantaggio del testing software dei processori è che, nel caso in cui si utilizzi una tecnica

software di basso livello, che preveda l’utilizzo di dispositivi appositi per il caricamento

del programma di test nel processore, tali dispositivi possono agire a frequenze di molto

inferiori a quelle della CPU, e sono pertanto di gran lunga più economici dei dispositivi

di at-speed-testing.

2.4 Self-testing software

Abbiamo visto come il testing hardware abbia la caratteristica di poter testare direttamente

i componenti strutturali della CPU, mentre quello software sia più economico e più veloce.

Sono state proposte tecniche software che uniscono i vantaggi dell’uno e dell’altro tipo di

testing: una delle più interessanti è sicuramente quella del self-testing software [13].

Tale tecnica si basa sulla conoscenza completa della descrizione a livello di Register

Page 18: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

18

Transfer e dell’instruction set del processore, e finora è stata con successo applicata a

processori molto semplici, come il Padawan (CPU a 8 bit con indirizzamento a 12 bit per

complessivi 4 KB di memoria).

Le fasi in cui si articola sono tre:

1. Estrazione dell’informazione

2. Selezione dell’istruzione

3. Selezione dell’operando

Nella fase di estrazione dell’informazione, partendo dall’instruction set e dalla

descrizione a livello RT, si individuano i componenti interessati dall’istruzione e gli effetti

che subisce.

Per ogni istruzione I e per ogni componente C vengono estratte le seguenti informazioni:

L’operazione O che il componente esegue, e i segnali di controllo abilitati dall’unità di

controllo per eseguire l’operazione

Per ogni operazione O, i registri interni di cui O fa uso, e la memoria che impiega per

controllo e per conservare i dati, insieme alle loro caratteristiche di osservabilità e di

controllabilità.

A partire da queste informazioni è possibile associare i segnali di controllo alle singole

istruzioni del processore e catalogare le istruzioni in base alle proprietà di osservabilità e di

controllabilità dei registri del processore e di memoria di cui l’istruzione fa uso [13].

La fase di selezione dell’istruzione prevede, per ogni componente C, l’insieme delle

operazioni OC che è in grado di eseguire.

Definiamo IC,O l’insieme delle istruzioni che durante la loro esecuzione comportano

l’attivazione degli stessi segnali di controllo, in modo da far eseguire al componente C

l’operazione O.

È evidente che, per come sono stati definiti gli insiemi, esiste almeno un’istruzione I che

faccia sì che il componente C esegua l’operazione O, ovvero 𝐼𝐶,𝑂 ≠ ∅.

Le istruzioni che appartengono a IC,O avranno diverse caratteristiche di osservabilità e di

controllabilità in quanto, ogni volta che l’operazione O viene eseguita, gli output del

componente C saranno registri con diverse caratteristiche di osservabilità, e a loro volta gli

Page 19: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

19

input saranno registri interni con diverse caratteristiche di controllabilità. Si sceglie quindi

un’istruzione I dall’insieme 𝐼𝐶,𝑂 in base ai seguenti passaggi [13]

1. Scartare le istruzioni 𝐼 ∈ 𝐼𝐶,𝑂 tali che quando O viene eseguita, l’uscita di C

non viene propagata ad un registro interno al processore. Tale criterio si basa

sul fatto che, se anche un componente è in uno stato di errore, se la sua uscita

non raggiunge i registri del processore, l’errore non si propagherà.

2. Ordinamento delle istruzioni in un’Instruction Priority List (IPL) secondo

quanto individuato dalla fase di estrazione dell’istruzione e in base ai seguenti

due passaggi.

3. Siano 𝐼𝐴, 𝐼𝐵 ∈ 𝐼𝐶,𝑂è prioritaria rispetto a 𝐼𝐵 (ovvero è in una posizione più alta

nell’IPL) se 𝐼𝐴 richiede un minor numero di operazioni nel propagare l’uscita

di C in un registro del processore (ovvero 𝐼𝐴 è più facilmente osservabile di

𝐼𝐵.

4. Se 𝐼𝐴 e 𝐼𝐵hanno la stessa priorità, si sceglie quella che richiede una sequenza

di istruzioni più piccola per generare uno specifico pattern di test nel registro

del processore che fa da input al componente C.

Va sottolineato che i passaggi sono stati definiti in maniera generale, senza ottimizzazione

rispetto a un determinato componente: in tal caso andrebbero modificati in modo da essere

più efficienti.

Nella fase di selezione dell’operando si selezionano gli operandi deterministici in modo

da ottenere la più alta copertura di fallimenti strutturali.

Una volta applicata l’istruzione, il processore eseguirà una STORE in modo da conserva il

risultato del test in memoria.

Se l’uscita del componente testato non è direttamente propagata ad uno dei registri della

CPU, sarà necessario eseguire un’istruzione aggiuntiva per memorizzare l’output del

componente in un registro [13].

A seconda della categoria a cui il componente appartiene (moduli funzionali, registri,

Page 20: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

20

elementi logici) avremo bisogno di un pattern di test diverso.

Anche nel caso in cui il componente sia difficile da testare, questa tecnica prevede l’uso di

operazioni logico-aritmetiche molto semplici (ADD, MULTIPLY, AND) generate on-chip

e organizzate in cicli efficienti, contrariamente a quello che avviene nel caso delle

tradizionali tecniche pseudo-casuali, che richiedono l’uso di un LFSR (linear feedback shift

register), un registro i cui dati di ingresso sono determinati da una funzione dello stato

interno: tali tecniche fanno uso di operazioni complesse, come controlli di parità, operazioni

bit a bit, e shifting, che producono anche programmi più lunghi.

Possiamo sintetizzare le operazioni in uno pseudo-codice:

𝑝𝑒𝑟 𝑜𝑔𝑛𝑖 𝐶𝑜𝑚𝑝𝑜𝑛𝑒𝑛𝑡𝑒 𝐶 {

𝑝𝑒𝑟 𝑜𝑔𝑛𝑖 𝑂𝑝𝑒𝑟𝑎𝑧𝑖𝑜𝑛𝑒 𝑂 ∈ 𝑂𝐶 {

𝑑𝑒𝑓𝑖𝑛𝑖𝑟𝑒 𝑙′𝑖𝑛𝑠𝑖𝑒𝑚𝑒 𝐼𝐶,𝑂

𝑠𝑐𝑒𝑔𝑙𝑖𝑒𝑟𝑒 𝐼 ∈ 𝐼𝐶,𝑂 𝑖𝑛 𝑏𝑎𝑠𝑒 𝑎 𝑐𝑜𝑛𝑡𝑟𝑜𝑙𝑙𝑎𝑏𝑖𝑙𝑖𝑡à 𝑒 𝑜s𝑠𝑒𝑟𝑣𝑎𝑏𝑖𝑙𝑖𝑡à

𝑢𝑠𝑎𝑛𝑑𝑜 𝐼, 𝑎𝑝𝑝𝑙𝑖𝑐𝑎𝑟𝑒 𝑝𝑎𝑡𝑡𝑒𝑟𝑛 𝑑𝑒𝑡𝑒𝑟𝑚𝑖𝑛𝑖𝑠𝑡𝑖𝑐𝑖 𝑎𝑔𝑙𝑖 𝑖𝑛𝑝𝑢𝑡 𝑑𝑖 𝐶

}

𝑠𝑒 𝑙𝑎 𝑐𝑜𝑝𝑒𝑟𝑡𝑢𝑟𝑎 𝑑𝑒𝑖 𝑓𝑎𝑙𝑙𝑖𝑚𝑒𝑛𝑡𝑖 è ≥ 𝑑𝑖 𝑞𝑢𝑒𝑙𝑙𝑎 𝑑𝑒𝑠𝑖𝑑𝑒𝑟𝑎𝑡𝑎

𝑒𝑠𝑐𝑖

}

È da notare che può esistere un’istruzione I che stimoli contemporaneamente operazioni

diverse in componenti diversi, ovvero 𝐼𝐶1,𝑂1 ∩ 𝐼𝐶2,𝑂2

≠ ∅ .

Se le uscite dei componenti C1 e C2 vengono propagate ai registri della CPU, anche se il

test è stato progettato per uno dei due componenti, possiamo anche controllare eventuali

fallimenti dell’altro. In tal modo possiamo testare un componente anche in casi di test

progettati per un altro, riducendo il numero di casi di test che si avrebbe se li progettassimo

per ogni singolo componente invece che per i componenti nel complesso: pertanto per

ridurre il numero di test necessari, dovrebbero essere definiti prima quelli le cui istruzioni

attivano il maggior numero di altri componenti [13].

Page 21: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

21

Infine, una delle caratteristiche più importanti di tale metodologia di testing è che viene sì

richiesta la descrizione del processore e l’instruction set, ma non la descrizione a livello di

gate né la sintesi in un linguaggio di descrizione hardware (come VHDL o Verilog).

Si riportano le percentuali di copertura ottenute mediante self-testing software relative ai

componenti della CPU Padawan; si noti che sono maggiori sia del full scan [13] (89.39% )

che del logic BIST [13] (88.69 %) applicate sullo stesso processore, che però prevedono

una modifica del circuito (e il peggioramento dei parametri di area e di prestazione).

Componente Copertura (%)

ALU 98.48

SHU 93.82

PC 88.10

AC 98.67

IR 98.26

MAR 97.22

SR 92.13

CTRL 85.52

Totale 91.10

Oltre al dato di copertura, è importante analizzare una tecnica di testing anche

considerandone la dimensione in byte della suite di test e dei dati di output e il tempo

necessario ad eseguirla. I dati sono riportati nella seguente tabella.

Numero di Istruzioni 444

Dimensione programma 885 B

Dimensione risposta 122 B

Cicli complessivi 16572

Rispetto ad altre tecniche simili [17] la tecnica proposta ha una copertura simile (le altre

arrivano fino al 91.42%), ma dimensioni e tempi di esecuzione minori [13].

Page 22: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

22

2.5 Pattern di Testing

Indipendentemente dal modo in cui viene svolto il testing della CPU (sia esso software o

hardware), viene svolto secondo un determinato modello o pattern.

Esistono diversi pattern di testing fondamentali [18]:

• Deterministico: sviluppato specificamente per un determinato circuito attraverso un

generatore automatico di test pattern (ATPG) o in base ad una simulazione di fallimento.

• Algoritmico: usato per il testing di strutture regolari e in base a modelli di fallimento

definiti.

• Esaustivo: tutti i possibili input (ad esempio per un contatore a n bit si possono testare

tutte le possibili 2n configurazioni). Questo pattern talvolta è difficile se non impossibile

da utilizzare e quando non lo è spesso ha costi molto elevati.

• Pseudo – esaustivo: si divide il circuito da testare in sotto-circuiti e si applicano

tecniche di testing esaustivo sui sotto-circuiti.

• Casuale: testing generato in maniera completamente casuale

• Pseudo – casuale: molto simile al testing casuale, ma definisce sequenze ripetibili di

testing

• Pseudo – casuale pesato: assegna un peso diverso alle diverse combinazioni possibili,

in modo che le più rilevanti si verifichino più spesso nella sequenza.

Page 23: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

23

Capitolo 3: Intel® Processor Diagnostic Tool

Intel è l’azienda leader nel settore dei dispositivi a semiconduttore come microprocessori,

memorie, dispositivi per telecomunicazioni e sistemi integrati. Fondata nel 1968 come

Integrated Electronics Corporation, è uno dei maggiori produttori di processori per sistemi

safety critical. Fornisce una suite di test per processori chiamata Intel Processor Diagnostic

Tools, scaricabile gratuitamente dal loro sito [19], compatibile con Windows e con Linux

e per architetture x86 e a 64 bit.

Vengono distribuiti: un programma dotato di interfaccia grafica in grado di eseguire

automaticamente tutti i test in maniera sequenziale, i singoli programmi di test, eseguibili

mediante riga di comando, i cui risultati vengono raccolti in un documento di testo e i codici

sorgente: in questo modo i test possono essere facilmente modificati, estesi o integrati in

altri programmi.

3.1 Programmi di test

La suite di test Intel Diagnostic Tool include i seguenti programmi di test:

• Genuine Intel: verifica che il processore su cui si stanno eseguendo i test sia

effetivamente un processore Intel originale e quindi ci assicura che il

processore non è contraffatto e che non sia di un altro produttore.

• Temperature: controlla la temperatura attuale del processore e, di default, il

test è negativo se la temperatura è almeno un grado inferiore alla temperatura

massima in cui il processore dovrebbe funzionare, positivo altrimenti. Permette

di modificare la differenza rispetto alla temperatura massima (ad esempio si

può modificare il criterio richiedendo che la temperatura sia almeno 30 gradi

inferiore al massimo, o anche meno nel caso in cui si stia testando il processore

Page 24: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

24

a basso carico e si voglia essere sicuri che la temperatura minima abbia un

valore accettabile).

• Brand string: estrae dal processore una stringa contente informazioni, come

modello, generazione e frequenza di funzionamento e la confronta con quanto

definito in BrandString_LocalConfig.xml: se la stringa inizia per Intel ®, è

concatenata con una stringa intermedia (Core, Atom, Pentium), presenta la

parola CPU ed è concatenata con una @, la stringa è ritenuta valida.

• CPU Frequency: verifica che la frequenza della CPU sia nei limiti di quella

prevista per il processore testato. La frequenza può essere calcolata in due

modi, il primo che restituisce la massima frequenza possibile, il secondo che

valuta la frequenza a cui effettivamente il processore sta operando.

• Floating Point: esegue una valutazione dei FLOPS ovvero delle operazioni a

virgola mobile (floating point) eseguite in un secondo. Il test esegue cicli di

operazioni (14400000 ad ogni ciclo) il cui risultato viene confrontato con

quello atteso per determinare la correttezza delle stesse. Il test riporta anche il

numero di eventuali errori.

• Prime Number generator: valuta la velocità della CPU di poter generare

correttamente numeri primi. Il test considera i numeri interi fino a 10000000,

applica un setaccio per eliminare i non primi e verifica che i numeri rimanenti

siano primi.

• Cache: accerta la presenza di cache e relative dimensioni: vengono valutate le

dimensioni della cache dati e istruzioni di livello 1, e le dimensioni delle cache

di livello 2 e di livello 3.

• MMXSSE: esamina la compatibilità del processore con i set di istruzioni

MMX e SSE (fino alla versione 4.2). Si tratta di istruzioni del tipo single

instruction, multiple data, utilizzate soprattutto per la grafica e per

l’elaborazione numerica dei segnali.

• AVX: controlla che il processore sia compatibile con il set di istruzioni

Advanced Vector Extension, di tipo SIMD, che migliorano le prestazioni siano

Page 25: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

25

per la modellazione 3D che per il calcolo scientifico, con il set di istruzioni

AES per la crittografia, e con il set PCLMULQDQ per la moltiplicazione ad

operandi a 64 bit senza riporto.

• IMC: misura la memoria, confronta il risultato del test con la quantità attesa

(comunicata dal sistema operativo) ed effettua delle semplici operazioni sulla

memoria.

• PCH: restituisce il modello del chipset (circuiti integrati nella scheda madre

che dirigono il traffico di informazioni tra periferiche, CPU, RAM e bus di

sistema), il suo stepping (versione), elenca le porte e i dispositivi che vi sono

collegati.

• IGD: controlla se nel processore è presente un dispositivo grafico integrato

Intel, e, nel caso affermativo, ne indica la generazione, attraverso un confronto

tra la stringa letta e un archivio di valori attesi per le varie generazioni.

• GFX: esercita la GPU facendo uso di due applicazioni OpenGL, una per la

grafica in due dimensioni, una in 3D,

• CPU load: carica la CPU al massimo con operazioni matematiche per un

intervallo di tempo prefissato e verifica che l’applicazione non fallisca.

3.2 Analisi dei codici sorgenti

Attraverso l’analisi dei codici sorgenti otteniamo maggiori informazioni a basso livello dei

programmi di test, in particolare nelle sezioni che operano mediante linguaggio

assemblativo, si procede quindi ad uno studio dei singoli programmi di test. L’analisi è

stata condotta facendo uso del compilatore Intel® e di Microsoft Visual Studio e si sono

applicate tecniche di reverse engineering in modo da produrre i seguenti documenti che

permettono di comprendere cosa i vari test svolgano e, cosa ancora più interessante e

significativa, come lo svolgano: infatti di tali test è fornita una documentazione sommaria

che però spiega unicamente come usarli ma non come funzionino.

3.2.1 Genuine Intel

Il programma di test GenIntel come primo passaggio effettua una pulizia del registro EAX

Page 26: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

26

a 32 bit (accumulatore), attraverso l’istruzione:

𝑥𝑜𝑟 𝑒𝑎𝑥, 𝑒𝑎𝑥

poiché la xor di una stringa di bit con se stessa restiuisce sempre una stringa di 0 (infatti la

xor restituisce 0 se due bit sono uguali): ciò è necessario in quanto la successiva istruzione:

𝑐𝑝𝑢𝑖𝑑

produce risultati diversi in base al contenuto di EAX [20]; per far sì che venga restituito il

Vendor ID (la stringa “GenuineIntel”) si deve avere EAX = 0. Si tenga conto che il valore

massimo che EAX può assumere dipende dal set di funzioni che si vuole usare [20]: nel

caso di funzioni per informazioni di base sul processore , il valore massimo viene ricavato

nel modo in cui si descrive di seguito; nel caso del set di istruzioni per informazioni

avanzate sul processore, è necessaria l’istruzione 𝑚𝑜𝑣 𝑒𝑎𝑥, 8000000ℎ: il massimo valore

inseribile in EAX quando si chiama CPUID per istruzioni avanzate verrà mostrato proprio

in EAX (da Pentium 4 fino a Skylake il massimo valore di EAX è 8000 0008).

L’effetto di tale istruzione nei registri è:

• Nel registro EAX viene inserito il massimo valore che lo stesso registro può

contenere all’atto della chiamata di CPUID riguardanti informazioni di base

della CPU

• In EBX, ECX, EDX la stringa “GenuineIntel” codificata in ASCII, secondo la

seguente configurazione:

Registro Bit 31-24 Bit 23-16 Bit 15-8 Bit 7-0

EBX u (75) n (6E) e (65) G (47)

EDX I (49) e (65) n (6E) i (69)

ECX l (6C) e (65) t (74) n (6E)

Per poter correttamente ricostruire la stringa abbiamo due problemi: mentre i caratteri ce li

aspetteremmo su un byte, sono contenuti in un registro da 4, e nella manipolazione

dobbiamo porre attenzione nel modo con cui ricostruiamo la stringa.

Per ovviare al primo problema, si fa uso, per ognuno dei registri general purpose, dei registri

H (alto, bit 15-8) e L (basso, bit 7-0), ciascuno dei quali è a 8 byte, un carattere ASCII:

necessariamente la stringa di bit deve però essere ruotata per poter avere il giusto carattere

Page 27: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

27

nella posizione desiderata. Quindi, per ognuno dei registri general purpose vengono

eseguite le seguenti istruzioni (a titolo di esempio si fa uso di EBX, ma gli altri due registri

vengono manipolati con tecniche simili, a parte l’incremento dell’indice del vettore di

caratteri e la terminazione con il carattere nullo alla fine della stessa):

𝑚o𝑣 𝑒𝑎𝑥, 𝑒𝑏𝑥

𝑚𝑜𝑣 𝑠𝑆𝑦𝑠𝑇𝑦𝑝𝑒[0], 𝑎𝑙

𝑚𝑜𝑣 𝑠𝑆𝑦𝑠𝑇𝑦𝑝𝑒[1], 𝑎ℎ

𝑠ℎ𝑟 𝑒𝑎𝑥, 16

𝑚𝑜𝑣 𝑠𝑆𝑦𝑠𝑇𝑦𝑝𝑒[2], 𝑎𝑙

𝑚𝑜𝑣 𝑠𝑆𝑦𝑠𝑇𝑦𝑝𝑒[3], 𝑎ℎ

ovvero sposto il contenuto del registro general purpose in EAX, costruisco la stringa

sSysType prelevando il primo carattere, poi il secondo: per utilizzare gli altri due usando

registri a 8 bit effettuo lo shift a destra di 16 bit e prelevo il terzo e il quarto carattere.

3.2.2 Temperature

Il programma di test temperature verifica che la temperatura del processore si trovi al di

sotto di una soglia prefissata. La logica del test si trova fondamentalmente nella procedura

void Temperature(unsigned long long *LSIZE) , in cui prima si procede ad un

controllo del più grande opcode supportato per le funzioni standard eseguibili da CPUID

come descritto prima, mediante il codice: mov eax, 0

CPUID

mov Avail, eax

la variabile Avail conterrà quindi l’opcode standard massimo. Successivamente dobbiamo

controllare che Avail sia maggiore o uguale di 6𝐻𝐸𝑋 (ciò è vero da Pentium D in poi) per

avere la sicurezza che la funzione che verifica la presenza del sensore di temperatura sia

supportata. Verificato questo, allora è possibile eseguire: mov eax, 0x6

mov ecx, 0

CPUID

and eax, 0x1

mov Sensor, eax

Page 28: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

28

che, come detto, verifica la presenza del sensore di temperatura (e anche di funzionalità di

gestione del consumo energetico); il primo è presente se il bit 0 di EAX è alto dopo

l’esecuzione di CPUID (il valore di EAX viene memorizzato nella variabile Sensor), ne

consegue che bisogna assicurarsi che Sensor = 1. Accertato questo, i passaggi successivi

sono strettamente legati al modo in cui i processori Intel misurano la temperatura [21]: infatti

entra in gioco la temperatura 𝑇𝐽 o temperatura di giunzione, misurata attraverso una

termocoppia posta sul diffusore di calore del processore; tale temperatura solitamente varia

tra gli 85 °C e i 109 °C. Un registro MSR (Model Specific Register, un registro utilizzato

per il controllo o il debugging) conterrà la temperatura attuale, tuttavia espressa come ∆𝑇

rispetto a 𝑇𝐽 da cui ne deriva che la temperatura della CPU, o 𝑇𝐶𝑃𝑈 = 𝑇𝐽 − ∆𝑇 . Ritornando

al codice vero e proprio, inizialmente verifichiamo che una lettura valida sia presente (si

controlla che il MSB di EAX sia alto): while (valid != 0x80000000)

{Rdmsr(0x19C, &RetEAX, &RetEDX);

OrgEAX = RetEAX;

valid = (RetEAX &= 0x80000000 }

si noti la presenza dell’istruzione Rdmsr, deputata alla lettura dei registri MSR, il cui

indirizzo viene specificato come parametro del metodo. Accertatisi che una lettura valida

della temperatura sia presente, si procede a prelevarla: if (valid == 0x80000000)

{ RetEAX = OrgEAX;

RetEAX &= 0x7F0000;

RetEAX = RetEAX >> 16;

LSIZE[0] = RetEAX;}

il successo del test viene valutato attraverso un confronto tra ∆𝑇, ossia la differenza rispetto

alla temperatura di giunzione, e la soglia desiderata. Se la prima è maggiore di quest’ultima

vi è un successo del test, altrimenti un fallimento.

3.2.3 Brand String

Il programma di test “BrandString” preleva una stringa detta Brand String dal processore

facendo uso tre volte dell’istruzione CPUID, ciascuna delle quali con un valore diverso

contenuto in EAX; avremo quindi un programma che può essere riassunto in questo modo:

𝑚𝑜𝑣 𝐸𝐴𝑋, 0𝑥80000002

𝐶𝑃𝑈𝐼𝐷

Page 29: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

29

𝑝𝑟𝑒𝑙𝑒𝑣𝑜 𝑙𝑎 𝑝𝑟𝑖𝑚𝑎 𝑝𝑎𝑟𝑡𝑒 𝑑𝑒𝑙𝑙𝑎 𝐵𝑟𝑎𝑛𝑑 𝑆𝑡𝑟𝑖𝑛𝑔 𝑑𝑎 𝐸𝐴𝑋, 𝐸𝐵𝑋, 𝐸𝐶𝑋, 𝐸𝐷𝑋

𝑚𝑜𝑣 𝐸𝐴𝑋, 0𝑥80000003

𝐶𝑃𝑈𝐼𝐷

𝑝𝑟𝑒𝑙𝑒𝑣𝑜 𝑙𝑎 𝑠𝑒𝑐𝑜𝑛𝑑𝑎 𝑝𝑎𝑟𝑡𝑒 𝑑𝑒𝑙𝑙𝑎 𝐵𝑟𝑎𝑛𝑑 𝑆𝑡𝑟𝑖𝑛𝑔 𝑑𝑎 𝐸A𝑋, 𝐸𝐵𝑋, 𝐸𝐶𝑋, 𝐸𝐷𝑋

𝑚𝑜𝑣 𝐸𝐴𝑋, 0𝑥80000004

𝑝𝑟𝑒𝑙𝑒𝑣𝑜 𝑙𝑎 𝑡𝑒𝑟𝑧𝑎 𝑝𝑎𝑟𝑡𝑒 𝑑𝑒𝑙𝑙𝑎 𝐵𝑟𝑎𝑛𝑑 𝑆𝑡𝑟𝑖𝑛𝑔 𝑑𝑎 𝐸𝐴𝑋, 𝐸𝐵𝑋, 𝐸𝐶𝑋, 𝐸𝐷𝑋

Per quanto riguarda il prelievo della Brand String, il procedimento è lo stesso di quanto

visto con Genuine Intel: ogni registro contiene quattro lettere; le singole lettere sono

ordinate da destra a sinistra e quindi mentre le prime due possono essere sempre prelevate

facendo riferimento ai “sottoregistri” alto e basso del registro in oggetto, le altre due, per

essere utilizzate, hanno bisogno di uno shift a destra, analogamente a quanto abbiamo visto

prima.

La stringa così costruita è chiamata sBrandVal. Si verifica che tale stringa rispetti la sintassi

delle Brand String Intel; ciò viene fatto applicando le regole trovate in

BrandString_LocalConfig.xml, che vengono memorizzate in una variabile del tipo

RapidXMLData. Le regole sintattiche prevedono che la BandString:

1. Inizi per Intel(R)

2. Deve essere composta da una delle seguenti “sottostringhe”: Core e (TM),

Celeron(R), Pentium(R), Atom e (TM), Xeon(R).

3. Deve essere presente la parola “CPU”

4. Deve essere presente il carattere “@”, che viene utilizzato per indicare la frequenza

a cui quel modello opera.

Se tali regole sono rispettate, la Brand String risulta valida.

3.2.4 CPU Frequency

Il programma di test “cpufreq” ha il compito di misurare la frequenza del processore.

Esistono due metodi per farlo. Il primo è molto semplice e fa uso dell’istruzione

𝑅𝐷𝑇𝑆𝐶

Page 30: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

30

acronimo di “Read Time Stamp Counter”, il cui effetto è leggere il contenuto di un registro

a 64 bit che contiene il numero di cicli di clock compiuti dal processore. All’invocazione

di tale istruzione il contenuto di tale registro viene memorizzato in due registri a 32 bit,

EAX e EDX. Per memorizzare il valore iniziale del Time Stamp Counter utilizziamo una

variabile del tipo _int64 cyclesStart i cui bit più alti saranno quelli contenuti in EDX e quelli

più bassi quelli appartenenti a EAX, ovvero:

__𝑖𝑛𝑡64 𝑐𝑦𝑐𝑙𝑒𝑠𝑆𝑡𝑎𝑟𝑡;

𝑚𝑜𝑣 𝐷𝑊𝑂𝑅𝐷 𝑃𝑇𝑅 𝑐𝑦𝑐𝑙𝑒𝑠𝑆𝑡𝑎𝑟𝑡, 𝑒𝑎𝑥

𝑚𝑜𝑣 𝐷𝑊𝑂𝑅𝐷 𝑃𝑇𝑅[𝑐𝑦𝑐𝑙𝑒𝑠𝑆𝑡𝑎𝑟𝑡 + 4], 𝑒𝑑𝑥

codice simile va eseguito quando dobbiamo prelevare il numero di cicli di clock, tali

istruzioni saranno eseguite dopo un secondo utilizzando l’istruzione wait_mils(1000), ciò

che cambia è l’utilizzo di una variabile cyclesStop, mentre per il resto il codice è identico.

Il numero di cicli viene calcolato un numero di volte dipendente dal sistema operativo (10

volte in Windows, 1000 in Linux). La frequenza viene ottenuta a partire dai cicli misurati,

che vengono divisi per il numero di misurazioni e normalizzati in modo da verificare se il

suo valore rientra nell’intervallo che va dalla frequenza nominale (estratta mediante il test

Brand String) meno la tolleranza al valore ottenuto sommando la frequenza nominale alla

tolleranza. Così facendo misuriamo però la massima frequenza teorica. Il secondo metodo

è più complesso e accurato e fa uso dei registri APERF e MPERF: il primo “conta” solo se

il processore logico è attivo, il secondo sempre; pertanto il secondo metodo ci permette di

ottenere una misurazione più precisa, legata all’effettivo utilizzo del processore. La

frequenza viene calcolata in due passaggi: nel primo calcoliamo la frequenza TSC

nominale, nel secondo moltiplichiamo la frequenza nominale per il rapporto

APERF/MPERF (che rappresenta il duty cycle attuale).

Il calcolo della massima frequenza nominale avviene leggendo il valore di

MSR_PLATFORM_INFO e tenendo conto dell’impostazione di Power Management in cui

il processore attualmente si trova. Tale valore, contenuto nella variabile Max_Ratio del

codice sorgente, viene moltiplicato, a seconda del modello del processore per 100MHz o

133.33 MHz, ottenendo la massima frequenza nominale (variabile OperatingFreq).

Page 31: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

31

Come detto, la frequenza effettiva viene calcolata come:

𝑂𝑝𝑒𝑟𝑎𝑡𝑖𝑛𝑔𝐹𝑟𝑒𝑞 ∙𝐴𝑃𝐸𝑅𝐹

𝑀𝑃𝐸𝑅𝐹

In questo modo, abbiamo ottenuto un valore sulla frequenza a cui il processore opera legato

all’effettivo utilizzo dello stesso, e non in base ad un massimo teorico.

3.2.5 Floating Point

Il programma di test “math_fp” verifica la correttezza delle operazioni in virgola mobile.

Tale test consiste nella dichiarazione di un vettore i cui elementi sono numeri a sei cifre

decimali; diverse operazioni vengono eseguite, il cui risultato viene confrontato con quello

atteso: tale numero di confronto è presente in diverse versioni, con più o meno cifre dopo

la virgola, quella maggiormente definita ha ben trentuno decimali. Le operazioni vengono

eseguite per un tempo specificato dalla variabile “runtime” che può essere specificato

dall’utente e il cui valore di default è 2 secondi. Durante questo tempo vengono eseguiti

diversi cicli composti ognuno da 14400000 operazioni: vengono registrati eventuali errori

(e se il flag corrispondente è attivo, il test può bloccarsi al primo errore), e misurati anche

i MegaFLOPS (milioni di operazioni in virgola mobile eseguite al secondo) secondo la

formula:

14400000

1000000 ∙ ∆𝑡

con ∆𝑡 intervallo di tempo trascorso dal termine del ciclo precedente (o dall’inizo del test

se è la prima iterazione).

3.2.6 Prime number generation

L’eseguibile “Math_PrimeNum” genera numeri primi e misura la velocità in cui lo fa. Il

processo di generazione prevede la creazione di un vettore di interi, chiamato sieve, di

cardinalità definita dal parametro sievesize, di default pari a 10000000, i cui elementi sono

inizialmente tutti pari ad uno. Vengono posti a 0 gli elementi la cui posizione è maggiore o

uguale di due, e multipla di un numero il cui quadrato è minore di 10000000 (si tratta di un

“setaccio”, ovvero di una tecnica utilizzata per eliminare i numeri non primi), il cui codice

è:

Page 32: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

32

for (int i = 2; i * i < sievesize; i++)

if (sieve[i])

for (int j = i + i; j < sievesize; j += i)

sieve[j] = 0;

successivamente si genera, per 1000 volte, un numero a caso, e se l’elemento la cui

posizione nel vettore è pari a quel numero è uguale a 1, deve essere verificato che quel

numero è un numero primo

for (int randQty = 0; randQty < 10000; randQty++)

{ random_integer = rand() % 10000000 + 1;

(si noti l’errore di utilizzare, nella divisione in modulo, un valore costante e non il parametro

sievesize; un errore grave si verificherebbe nel caso di una riduzione del valore di sievesize,

in quanto il vettore accederebbe ad un’area di memoria che non gli appartiene, senza

neanche sollevare un’eccezione perché il controllo sulla correttezza dell’indice viene

eseguito solo usando il metodo at() e non quando si opera con [], conducendo a risultati

sicuramente sbagliati). Il test per verificare se il numero è primo consiste nel dividerlo per

tutti gli interi compresi tra due e la parte intera della radice quadrata, in quanto se un numero

non è primo ha sicuramente un fattore pari o minore della sua radice quadrata (escludendo

il caso in cui il numero sia un quadrato perfetto, nel secondo caso, se entrambe le radici

fossero maggiori della radice quadrata, il risultato sarebbe un numero, per assurdo,

maggiore di quello di cui dovrebbero essere fattori) if (sieve[random_integer])

{bool a = true;

for (double i = 2; i <= sqrt(random_integer); i++)

{int numberI = static_cast<int>(random_integer);

int iI = static_cast<int>(i);

if (numberI%iI == 0)

{a = false;

break;

}

}

if (a == false) //Non Prime Number

{a = true;

CycleErr += 1;}

else {

a = true;

}

Page 33: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

33

se trovo un divisore, esco dal ciclo e aggiungo uno al conteggio degli errori, altrimenti

arrivo alla parte intera della radice ed esco. La restante parte del codice prevede l’uscita

immediata dalla procedura se il flag di uscita al primo errore è alto e ho trovato un errore,

oppure il calcolo della velocità nel generare i numeri primi (per il valore di sievesize di

default sono 664579, numero memorizzato nella variabile TotalGenerated) diviso per il

tempo impiegato a generare i numeri primi e verificarne le proprietà (timeUpdateOPS).

Pertanto avremo che:

𝑂𝑝𝑒𝑟𝑎𝑡𝑖𝑜𝑛𝑠 𝑝𝑒𝑟 𝑠𝑒𝑐𝑜𝑛𝑑 = 𝑇𝑜t𝑎𝑙𝐺𝑒𝑛𝑒𝑟𝑎𝑡𝑒𝑑

𝑡𝑖𝑚𝑒𝑈𝑝𝑑𝑎𝑡𝑒𝑂𝑃𝑆

tale valore esprime proprio la velocità del processore nella generazione e nella verifica di

numeri primi.

3.2.7 Cache

Il programma “cache” misura la dimensione delle cache, livello per livello. Il codice

prevede l’esecuzione dell’istruzione 𝐶𝑃𝑈𝐼𝐷 con EAX = 0, un check su contenuto dello

stesso registro dopo l’esecuzione dell’istruzione (condizione necessaria è che il contenuto

sia maggiore di 4, in quanto quello è il valore da inserire in EAX per ottenere informazioni

sulla cache). Nelle seguenti operazioni: mov eax, 0x4

mov ecx, 0

CPUID

mov ULorgEAX, eax

and eax, 0xfc000000

shr eax, 26

add eax, 1

mov ULcores, eax

mov eax, ULorgEAX

and eax, 0x03FFC000

shr eax, 14

add eax, 1

mov ULThred, eax

mov ecx, 0

mov eax, 0x1

CPUID

and ebx, 0xFF0000

shr ebx, 16

mov ULLogIDs, ebx

le variabili ULThread, ULLogIDs e UlCores vengono utilizzati per memorizzare

Page 34: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

34

informazioni aggiuntive sul processore (cores, hyperthreading, ecc.), all’interno del vettore

𝐿𝑆𝐼𝑍𝐸, che nelle prime 4 posizioni conterrà informazioni sulla dimensione della cache, le

restanti 3 dati aggiuntivi. Segue un loop sulla variabile ULorgEAX (rappresentante i livelli

di cache), che inizialmente raccoglie informazioni su quattro parametri: associatività,

partizioni di linee fisiche, dimensione della singola linea, set. Successivamente tali

informazioni vengono utilizzate nella formula:

(𝑎𝑠𝑠𝑜𝑐𝑖𝑎𝑡𝑖v𝑖𝑡à + 1)(𝑙𝑖𝑛𝑒𝑒 𝑓𝑖𝑠𝑖𝑐ℎ𝑒 + 1)(𝑑𝑖𝑚𝑒𝑛𝑠𝑖𝑜𝑛𝑒 𝑙𝑖𝑛𝑒𝑎 + 1)(𝑠𝑒𝑡 + 1)

1024

che permette di calcolare la dimensione (in KB) della cache. Si tenga conto che per la Cache

di livello 1 vengono misurati sia lo spazio riservato ai dati che quello per le istruzioni.

3.2.8 MMXSSE

Il controllo del supporto alle istruzioni MMX e SSE (dalla versione 1.0 alla 4.2) viene

eseguito dal programma “mmxsse.exe” mediante dei metodi il cui comportamento prevede

l’esecuzione di CPUID con EAX=1,e la verifica che tale istruzione abbia posto a 1 dei flag

nei registri (su EDX abbiamo i flag relativi a MMX e SSE 1 e 2, su ECX quelli associati a

SSE 3, SSSE3, SSE 4.1 e 4.2). Una volta raccolte queste informazioni, si procede ad un

test delle istruzioni dei vari set.

Tale test risulta essere completo anche per un sistema safety-critical in quanto non si limita

a controllare la compatibilità del processore con l’instruction set in oggetto, ma verifica la

correttezza delle singole operazioni.

3.2.9 AVX

L’eseguibile “avx.exe” effettua un controllo sul supporto del processore ad AVX (istruzioni

a 256 bit per ottimizzare i calcoli a virgola mobile) hardware e software, e ad AES e

PCLMULQDQ in hardware. I tre controlli hardware vengono eseguiti in maniera molto

simile a quella del test precedente, e sono compito di una procedura che riceve in ingresso

il flag da valutare e lo controlla con l’istruzione CPUID configurata come visto prima. Il

testing del supporto software di AVX avviene testandone prima quello hardware e poi

eseguendo il codice assemblativo:

Page 35: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

35

mov eax, 1

cpuid

and ecx, 018000000H

cmp ecx, 018000000H;

jne NOT_SUPPORTED;

mov ecx, 0;

XGETBV;

and eax, 06H

cmp eax, 06H

jne NOT_SUPPORTED

mov eax, 1

mov val, 1

jmp DONE

NOT_SUPPORTED :

mov eax, 0

DONE :

che valuta i flag AVX e OSXSAVE : il secondo permette al sistema operativo di far

eseguire al processore il salvataggio dello stato esteso in un’area di memoria designata. Se

tale flag fosse basso non potremmo usare l’istruzione XGETBV successivamente. L’and

tra EAX e 06𝐻𝐸𝑋 ci permette di valutare se il sistema operativo supporta l’utilizzo dei

registri XMM e YMM per operazioni rispettivamente a 128 e 256 bit (anche se si tratta di

registri logici, in quanto se sono presenti anche i registri YMM, XMM sono in realtà i bit

meno significativi di YMM) necessari per il supporto software delle istruzioni MMX e

AVX. Dopo aver assegnato 1 a val (inizializzato a 0), usciamo. Se val vale 1 abbiamo

eseguito tutte le istruzioni e quindi siamo sicuri del supporto software di AVX, altrimenti

il sistema operativo non supporta tali istruzioni. In base all’esito dei controlli hardware e di

quello software, il programma procede ad eseguire le istruzioni dei set supportati.

3.2.10 IMC

“imc.exe” ha il compito di accertare la corretta comunicazione CPU-memoria, nonché

capacità e velocità di quest’ultima. Il programma di test inizialmente carica alcune

configurazioni parametriche di una CPU che non supportano il test IMC (contenuti in un

file XML GlobalConfig.xml, e ricavando delle stringhe di configurazione da confrontare a

quella prelevata). La configurazione della CPU corrente viene ricostruita (funzione

GetProcFamilyModel) facendo uso del ben conosciuto opcode CPUID con EAX = 1; nello

Page 36: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

36

stesso registro, avremo come output tre parametri fondamentali: famiglia, modello e

stepping della CPU, che preleveremo singolarmente mediante shift. Successivamente il

modello viene confrontato con quelli del file descritto precedentemente: nel caso sia uno di

quelli, il test termina. Nel caso contrario, il test prosegue prima inizializzando un valore di

memoria attesa e relativa tolleranza se impostato da riga di comando; in ogni caso si

procede poi a misurare la memoria fisica del sistema, ovviamente in modi diversi in base

al sistema operativo in esecuzione. Nel caso di riferimento di Windows, prima se ne

controlla la versione con una variabile di tipo OSVERSIONINFOEX; in base alla quale la

misurazione può avvenire in due modi diversi: da Windows Vista in poi con l’utilizzo della

funzione GetProcAddress i cui argomenti [22] sono un handle a una libreria dinamica (in

questo caso Kernel32.dll) e il nome della funzione di sistema desiderata

(GetPhysicallyInstalledSystemMemory), per versioni meno recenti si fa uso della struttura

dati MEMORYSTATUSEX e del metodo ullTotalPhys. Restituito il valore di memoria

fisica, eventualmente confrontato con quello atteso, si procede allo stress test della

memoria. Il programma di test si assicura che vi sia almeno un gigabyte di RAM libera, e

prosegue con le varie operazioni. La prima (Ones and Zeros Moving Inversions) consiste

nella scrittura di un vettore dinamico di char i cui elementi sono alternativamente 𝐹𝐹𝐻𝐸𝑋 e

0, con conseguente verifica di questa proprietà e misura del tempo impiegato. La seconda

(32Bits Sliding Ones) consiste nella costruzione di un vettore dinamico di int in cui ogni

valore è la divisione in modulo 32 della posizione occupata e successivo shift con 1,

(matematicamente equivale a inserire nel vettore elementi che sono la potenza di due

elevata alla posizione occupata modulo 32) a cui segue un controllo della velocità a cui

viene effettuato il test. Il terzo test (32Bits Sliding Zero) riempie il vettore con 0.

3.2.11 PCH

Il Test PCH ha il compito di controllare il chipset, sia per quanto concerne i dati di

produttore, modello e stepping, sia per verificarne il funzionamento e controllare le

periferiche che vi sono collegate. Dopo aver caricato le configurazioni possibili, contenute

nel file PCH_LocalConfig.xml, la prima operazione permette di controllare se il chipset del

Page 37: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

37

sistema supporta il test ( int IsPCHseries()); tale metodo controlla che si tratti di un

dispositivo Intel (IsIntelDevice), il prelievo delle informazioni vero e proprio avviene con

la funzione DeviceIoControl, una API Windows che permette di inviare uno specifico

codice ad un determinato driver [23]. Ottenuto il codice che individua il bus LPC (Low Pin

Count), si risale al Chipset di appartenenza, sfruttando l’associazione uno a molti che

sussiste tra quest’ultimo e l’ID dei bus. Successivamente si procede al prelievo dello

stepping in modo simile a quanto fatto per il bus LPC (GetPCHSteppingString). Raccolte

queste informazioni, si controlla il numero di bus PCI ed eventuali bridge di tipo PCI-PCI

(di solito non presenti in sistemi di uso personale, ma nei server [24]). Per ogni bus PCI si

elencano i dispositivi collegati (metodo PCIe). Vengono effettuati controlli anche su

dispositivi Serial Ata esterni (extSATA), sulle periferiche collegate al controller audio Intel

ad alta definizione (highDefAudio), su dispositivi collegati al controllore Gigabit LAN

(GigabitLan).

3.2.12 IGD

Il programma di test IGD verifica la presenza di Intel® Integrated Graphics sulla CPU su

cui vene eseguita: si tratta di driver grafici utilizzati nel caso di schede video integrate. La

funzione principale del test (IGDQUERY) procede inizialmente ad una veloce verifica di

alcune proprietà di base (verificando ad esempio che sia Intel) con la funzione che controlla

la Brand String e che abbiamo già analizzato precedentemente. Tale stringa diventa

l’argomento della funzione IGDMain, che prima preleva famiglia, modello e stepping del

processore (GetProcFamilyModel), poi verifica la generazione dello stesso chiamando la

funzione Checki3i5i7 che confronta il modello prelevato in precedenza con i parametri

presenti in un file XML contenente le diverse configurazioni (IGD_LocalConfig.xml) e

restituisce una variabile intera legata alla generazione. Il flusso di controllo del chiamante

viene determinato da questo parametro e dal Vendor ID, letto, in ultima analisi, con

DeviceIoControl; anche altri valori vengono letti, come Device ID, Revision ID, Graphics

Translation Table, Graphics Memory Range, Subsystem Vendor ID, Subsystem ID, Video

BIOS Rom Address, Graphic Mode, Video Disable. La presenza di IGD viene rilevata da

Page 38: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

38

una and tra il valore della generazione (come detto, restituito da Checki3i5i7) e dal

parametro Vendor ID (che deve essere 8086, codice che rappresenta un prodotto Intel). In

caso affermativo, vengono riportati anche gli ulteriori parametri elencati sopra, che vengono

manipolati in maniera leggermente diversa in base alla generazione. Tale test non opera in

maniera corretta se è presente una scheda video dedicata: in tal caso bisognerà scollegare

quest’ultima per fare in modo che operi quella integrata nella CPU.

3.2.13 GFX

Il programma di test GFX effettua due controlli: il primo sulla grafica in 2D, in cui viene

verificata la generazione di uno spettro di colori, e il secondo in 3D, in cui viene visualizzato

un cubo sulle cui facce sono applicate delle texture. Diversi parametri sono caricati da un

file XML di configurazione (come il tempo di esecuzione del test e il numero di rotazioni

del cubo, nome degli eseguibili per il test in 2D e in 3D). Successivamente al prelievo di tali

parametri avviene l’esecuzione dei programmi mediante la funzione int system (const

char* command), contenuta nella libraria cstdlib. Tuttavia dei due programmi che vengono

eseguiti per il controllo delle funzionalità grafica (vis2Dgfx.exe e visGFX1.exe) non

vengono forniti i codici sorgente, ma unicamente gli eseguibili. Il successo o il fallimento

dei due test viene determinato dal return code dei due sottoprogrammi.

3.2.14 CPU Load

Il programma di test CPU Load ha il compito di caricare la CPU di operazioni (creando

continuamente nuovi thread in modo da saturare la capacità di calcolo del processore)

mediante la funzione void CPULoad(int iHours, int iMins, int iSec) che può essere

utilizzata per uno stress del processore dalla durata anche di ore. Il ciclo di operazioni, che

rappresenta quindi il nucleo del programma stesso è:

double d1 = 2.1; double d2 = 3.3;

for (; msElapsed <= msTarget;) {auto b = async(add_async, d1, 0.0001); auto c = async(add_async, d2, 0.0001);

auto a = async(multiply, d1, d2); timeElapsed = clock() - start;

Page 39: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

39

msElapsed = timeElapsed / CLOCKS_PER_MS;}

in cui dopo aver dichiarato due variabili double (d1,d2), eseguiamo un ciclo che termina

solo dopo un intervallo di tempo (msTarget esprime i millisecondi del tempo di esecuzione

desiderato, msElapsed del tempo effettivamente trascorso). In tale ciclo calcoliamo a,b,c

ottenuti mediante le operazioni add_async e multiply (tali funzioni sono definite nello stesso

sorgente, ma si limitano a moltiplicare o aggiungere e restituirne il valore), e calcoliamo il

tempo trascorso dall’inizio del ciclo in termini di clock e ricaviamo i millisecondi trascorsi

dividendo i clock per il numero di clock per millisecondi. Poiché ogni iterazione del ciclo

confronta msElapsed con msTarget, al raggiungimento del numero di millisecondi

desiderato, si esce dal ciclo.

Page 40: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

40

Conclusioni

Dopo aver introdotto nel primo capitolo le caratteristiche di un sistema safety critical, aver

individuato nel secondo la componente più importante del controllo digitale nel processore

nel secondo, aver indicato nello stesso capitolo metodologie storiche, attuali e sperimentali

di testing, e aver condotto uno studio della suite di test Intel® Processor Diagnostic Tool

nel terzo, abbiamo a disposizione abbastanza informazioni per giungere a delle conclusioni

sul testing dei processori superscalari particolarmente importanti nel caso vengano utilizzati

per sistemi safety critical, ma che possono, tenendo conto dei requisiti meno stringenti,

essere allargate anche a casi più “tradizionali”.

4.1 Difetti di Intel® Processor Diagnostic Tool

Lo studio del codice sorgente di Intel® Processor Diagnostic Tool ci ha permesso non

solo di capirne il funzionamento, ma anche di scoprirne alcuni difetti. Alcuni di questi

difetti sono di tipo concettuali, legati quindi al test in sé e non alla modalità di

implementazione e vengono elencati di seguito.

Parametri significativi vengono tralasciati. Nel caso di Test Genuine Intel il contenuto

del registro EAX viene inspiegabilmente ignorato: infatti se è sicuramente utile verificare

l’autenticità del processore utilizzato, tramite questo test non si viene a conoscenza della

generazione del processore, ottenibile consultato proprio il contenuto di EAX dopo

l’esecuzione di CPUID. Basterebbe infatti controllare EAX per avere conferma se il nostro

processore, ad esempio modello i5, appartiene alla sesta generazione (Skylake) o alla quinta

(Ivy Bridge) e così via, in quanto in EAX, dopo l’esecuzione di CPUID, viene memorizzata

una stringa univoca per generazione. La generazione è sì parte della stringa che otteniamo

con il test Band String, ma quest’ultima è così piena di informazioni che richiede

Page 41: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

41

l’intervento umano per la consultazione e una buona conoscenza delle generazioni di Intel

(associazione nome-sarebbe automatizzabile: spesso è più facile avere errori sulla

generazione del processore, che non dell’autenticità dello stesso.

Alcuni test possono essere sostituiti dall’utilizzo di dispositivi elettronici. La

temperatura del processore è un aspetto importante per un sistema safety-critical. Delegare

al processore stesso tale misura oltre a farci perdere preziosi cicli di clock, nel caso in cui

siamo in una situazione di errore della CPU potrebbe anche darci misurazioni sbagliate (ad

esempio potrebbe darci come valida una temperatura al di sopra di quella massima a cui

dovrebbe operare): inoltre sensori che misurano la temperatura in maniera autonoma sono

particolarmente economici e solleverebbero il processore dall’onere, permettendo di

risparmiare non solo cicli di clock, ma anche di avere misure più affidabili e indipendenti

dallo stato del processore stesso. È evidente che in un sistema safety-critical la temperatura

del processore sarà valutata da un sensore e non da un programma in esecuzione sul

processore.

Controlli blandi. Il Test BrandString non risulta particolarmente utile per un sistema

safety-critical, se non una volta sola, ossia alla consegna delle board, per verificarne la

presenza del processore atteso. Successivamente, essendosi accertati della corrispondenza

del processore con il modello desiderato, tale test non sarà particolarmente significativo, in

quanto se anche la Brand String risultasse corrotta, sarebbe, molto probabilmente, indice di

uno stato di errore della CPU, che avrebbe già mostrato in altre situazioni. Inoltre, visto che

il test riguarda solo la correttezza della stringa, e non la corrispondenza di tutti i parametri

con i possibili modelli della Intel, risulterebbe comunque più utile il test GenuineIntel

modificato in maniera tale da introdurre il test riguardo alla generazione (proprio perché

Brand String si limita a valutare la correttezza sintattica).

In base a quanto detto la scelta più conveniente sarebbe rimodellare Brand String in modo

da confrontare una serie di parametri prelevati dalla CPU con quelli attesi, in modo da

verificare la completa aderenza del modello testato con quello atteso.

Per la complessità dei processori superscalari, alcuni test sono diventati meno

significativi che in passato. La frequenza a cui un processore opera è uno degli aspetti che

Page 42: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

42

è diventato più complesso all’evolversi dei processori. Basti pensare come ogni processore

sia composto da più core, e come nello stesso momento un core possa essere attivo e gli

altri spenti, e di come quindi il concetto di frequenza del processore sia diventato meno

importante che in passato (infatti se il programma è multithreaded, le prestazioni del singolo

thread sono influenzati dallo stato attuale del core su cui effettivamente sarà eseguito).

Inoltre la frequenza della CPU è un limite massimo teorico, in quanto se il nostro intento è

misurare le prestazioni a cui un sistema informatico può eseguire un programma, bisogna

tener conto del fatto che gli altri componenti operano ad una frequenza ben minore della

CPU, e operazioni come quelle sulla memoria di massa sono particolarmente lente. Per tale

motivo, il test “CPUFrequency” risulta essere utile solo per una verifica iniziale della

frequenza del processore, per verificarne in maniera veloce la corrispondenza con i valori

dichiarati. Nel caso in cui vogliamo effettivamente verificare le prestazioni del nostro

sistema, allora sarebbe ben più utile sviluppare i programmi facendo uso di Intel® VTune™

Amplifier, un tool di sviluppo sempre di Intel, che permette di raccogliere dati precisi sulla

prestazione del codice in termini di utilizzo di CPU, FPU, GPU, RAM e altri componenti,

con un overhead relativamente basso.

Il caso peggiore viene mancato e i casi analizzati non risultano essere particolarmente

significativi. Il test della FPU ricava correttamente i megaflops del processore

(misurandoli, senza limitarsi a presentarne il valore nominale). Tuttavia probabilmente il

test più significativo che potrebbe essere eseguito nell’ambito dei calcoli a virgola mobile

è quello della divisione per un numero prossimo allo 0, con un numero di cifre decimali

crescente, in modo da verificare non solo il numero massimo di cifre decimali che il

processore è in grado di gestire, ma anche per assicurarci che per numeri a risoluzione

minore non si incorra in un’errata approssimazione a 0. Questa considerazione è giustificata

dal fatto che mentre una operazione errata su un numero a virgola mobile può produrre un

output inesatto dalle conseguente più o meno importanti, una divisione per zero risulta

essere una condizione critica della CPU, che sicuramente porterà al fallimento del sistema:

avere una certezza di non dividere per 0 operando su numeri molto piccoli ci permette di

operare con linguaggi di programmazione ad alto livello senza preoccuparci che errori di

Page 43: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

43

questo tipo siano dovuti al processore in sé. Infine si potrebbe pensare ad un test che esegua

tutte o la maggior parte delle operazioni da usare in virgola mobile, mentre sul test proposto

da Intel si fa uso di somma algebrica e di moltiplicazione.

Presunzione, senza alcuna verifica, della correttezza di alcune operazioni. Nel test di

generazione dei numeri primi se ne controllano solo 10000 e nel caso in cui non vi sono

errori in quei diecimila, si considerano come correttamente generati tutti i numeri prima

(circa seicentocinquantamila nel caso di default): chiaramente in un test ci aspetteremmo

un controllo su ogni numero generato, il che rallenterebbe un po’ la procedura, ma ci

darebbe una garanzia assoluta sulla capacità di generare numeri primi (per non far pesare

troppo l’intervallo di verifica da quello di generazione, potremmo prima generare i numeri,

fermare il conteggio, verificarli e poi ottenere il numero di operazioni con il conteggio

bloccato all’ultimo istante di generazione).

Valutazione di parametri puramente nominali della componente in analisi senza alcun

test funzionale. Il test relativo alla cache è probabilmente quello il cui nome può

maggiormente trarre in inganno, in quanto la cache non viene in realtà mai testata in termini

di affidabilità o di latenza, ma ne vengono solo riportate le dimensioni. Proprio per la cache,

essendo un componente del processore (e non una sua funzionalità come un set di

istruzioni), sarebbe necessario un test che metta effettivamente in esercizio la cache

effettuando trasferimenti di dati. Per tali motivi, per un sistema safety-critical la cache andrà

testata in altro modo, ad esempio utilizzando una delle tecniche descritte nel capitolo 2. Il

test IGD ha il problema principale di limitarsi a verificare la presenza dei driver grafici Intel

attraverso il prelievo di parametri della macchina su cui viene eseguito e il confronto con

configurazioni standard, senza però verificarne il corretto funzionamento: potrebbe essere

possibile che seppur i driver siano nominalmente supportati, per qualche motivo non

funzionino o lo facciano solo in parte (banalmente, potrebbe succedere che delle

funzionalità introdotte con driver recenti non siano supportati su versioni precedenti) :

informazioni di questo tipo possono essere molto utili.

Alcuni parametri non possono essere definiti in maniera assoluta, ma vanno testati

eseguendo l’applicazione target. Il test IMC è completo nel valutare la memoria del

Page 44: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

44

sistema che lo esegue, mentre i tre test funzionali su di essa possono darci informazioni sul

corretto funzionamento di una parte della stessa, ma non ci assicurano la piena operatività

di un programma in esecuzione sulla CPU nel caso questo vada a saturare o quasi la RAM:

tale test sarebbe più utile ristrutturato per conoscere il comportamento dell’applicazione nel

caso peggiore, e può essere facilmente implementato. Così come il programma CPULoad

è completo nel valutare, anche se attraverso operazioni ripetitive e semplici, il corretto

comportamento del processore in condizioni di carico massimo. Tuttavia bisogna avere

sempre ben presente che un test del genere può non darci in maniera completa informazioni

sul comportamento del processore nel generico caso di carico massimo: ad esempio

potremmo avere errori se il processore è sovraccaricato con istruzioni particolari o con una

determinata combinazione delle stesse, o ancora potremmo avere problemi a più alto livello

in termini di tempi o correttezza di risultati dovuti a un eccessivo carico della CPU. Per

avere una copertura significativa del comportamento in caso di carico notevole sul

processore si consiglia quindi di verificare il funzionamento del programma nel caso di

input particolarmente complessi e condizioni di funzionamento il più possibile complicate,

essendo quindi sicuri di rientrare nel worst-case per fornire una stima del tempo di

esecuzione e soprattutto di verificare il corretto funzionamento del programma.

Terminano qui i difetti “concettuali” legati a Intel® Diagnostic Tool: ne sono stati

individuati ulteriori, legati però alla modalità di implementazione.

Non viene fornito il codice sorgente effettivo del test. GFX ha praticamente la totalità

della logica nei due eseguibili di cui non viene fornito il codice sorgente. Per tale motivo,

ciò che viene distribuito è sostanzialmente un semplice main che lancia gli eseguibili e ne

preleva i codici di ritorno, senza alcuna caratteristica o funzionalità che possa essere in

qualche modo legata alla grafica; pertanto, la componente “in chiaro” non risulta essere di

nessun interesse. Nell’ambito del testing di processori per sistemi di qualsiasi tipo (non solo

safety-critical quindi), ci si aspetta il rilascio dei sorgenti completo del codice sorgente.

Hard-coding dei parametri. Nel test di generazione dei numeri primi, il parametro che

rappresenta i numeri presi in considerazione (primi e non), e che quindi indica anche la

dimensione del vettore su cui si opera, è indicato dalla variable “sievesize”, di default

Page 45: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

45

uguale a 10000000. Nella prima parte del codice si opera correttamente attraverso la

variabile stessa, ma quando si genera un numero casuale, la divisione in modulo non viene

fatta utilizzando sievesize, ma attraverso il suo valore di default. I potenziali effetti negativi

di una riduzione della variabile sievesize congiuntamente all’hard-coding (utilizzare un

valore costante al posto della variabile) sono stati già discussi nel capitolo dedicato al test

Prime number generation (accesso ad una locazione di memoria non riservata al vettore).

Funzioni precedentemente definite non vengono utilizzate, ma ne viene copiato il

codice. Ciò è stato riscontrato nel corpo della funzione di verifica al supporto software ad

AVX , cioè bool DetectSWFeature(unsigned int feature). Come detto tale metodo

controlla inizialmente il supporto hardware a tale set di istruzioni e poi procede alla

valutazione. Tuttavia, invece di chiamare la procedura deputata alla verifica del flag

indicante il supporto hardware come ci aspetteremmo, ossia DetectHWFeature

(AVXHWFlag), viene ripetuto il codice di tale funzione all’interno della precedente.

Questo approccio anti-modulare avrà come sgradevole side-effect che eventuali modifiche

al corpo di quest’ultima funzione non avranno conseguenze sulla prima, a meno di

cambiamenti del codice. Ciò è evidentemente antinomico rispetto alle corrette tecniche di

programmazione.

Non è definita un’unica libreria a cui i tutti sorgenti di test possano fare riferimento, ma

ogni programma ridefinisce tutte le funzioni utilizzate. Ciò è vero sia per alcune funzioni

di utilità, come GetProcFamilyModel, dichiarato e definito sia in IMC che in IGD che per

interi test.

Infatti si nota una ripetizione del test Brand String all’interno di IMC, che non viene quindi

importato da una libreria di Brand String: anche in questo caso ci troviamo di fronte al

problema che se modificassimo il codice di quest’ultimo test non avremmo il cambiamento

desiderato anche in IMC. Sarebbe più opportuno definirne un header e un sorgente unico e

poi farne riferimento nei singoli test, permettendo che i codici che la usano siano allineati

ai suoi cambiamenti.

Incertezza sulle convenzioni di naming di funzioni e variabili. È un problema generale,

ma si nota in particola in CPULoad, infatti i nomi delle funzioni siano assegnati con delle

Page 46: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

46

convenzioni talvolta rispettate (add_async) e talvolta ignorate (multiply, senza quindi

async), generando confusione nel momento in cui si voglia far uso dei metodi dichiarati e

definiti nella suite Intel Diagnostic Tools: per un’azienda così importante è singolare come

non si possa avere una certezza sulle convenzioni utilizzate per descrivere funzioni. Tale

incertezza si è manifestata un po’ in tutti i programmi della suite, anche sui nomi assegnati

ai metodi che contengono gran parte della logica di test : in alcuni casi abbiamo avuto nomi

del tipo RunTest(), in altri casi Test(), il che costringe a verificare manualmente, di volta in

volta, il nome assegnato all’effettiva funzione di test.

A questi fattori se ne aggiungono altri indiretti, relativi alla documentazione, scarna e che

indica solo gli obiettivi dei test, senza nessun indizio su come operino, talvolta afflitta da

errori tipografici [25] o evidentemente localizzati mediante l’uso di un traduttore

automatico [26].

Intel® Processor Diagnostic Tool è, almeno allo stato attuale, una suite non adatta al testing

di processori per sistemi safety-critical, poiché la gran parte dei test può essere utile per un

processore in esecuzione su un Personal Computer, per utenti che vogliono verificare in

modo rapido se i problemi che si stanno verificando sul computer siano direttamente

imputabili al processore. Come visto, gran parte delle informazioni sulla CPU necessarie

per sistemi safety-critical talvolta non sono raccolte oppure lo sono in maniera grossolana.

La ristrutturazione di Intel® Processor Diagnostic Tool per sistemi critici può avvenire

seguendo l’analisi compiuta in questo testo, ma sicuramente non può essere completa senza

l’intervento e la collaborazione di Intel.

4.2 Elementi di resistenza a un testing efficace

Alcuni difetti strutturali di Diagnostic Tool non sono però casuali, e rientrano in una

problematica più ampia del testing in generale, soprattutto per i processori. Diverse ragioni

fanno sì che il produttore non possa darci tutte le informazioni necessarie a progettare test

che si avvicinino all’efficacia massima.

Timore di rivelare la struttura del prodotto. Informazioni troppo dettagliate sulla

struttura di un dispositivo elettronico la rendono replicabile da aziende concorrenti. Ecco

Page 47: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

47

perché i diagrammi dei data sheet si fermano ad un livello di dettaglio che è un

compromesso tra utilità e segretezza, ed inoltre si concentrano solo su aree ritenute

importanti per l’utilizzo (mentre il testing richiederebbe diagrammi dettagliati dell’intero

dispositivo).

Volontà di non rendere pubbliche strategie e algoritmi di basso livello. Il test della

cache si limita a valutare la dimensione della stessa proprio per questo: infatti se il

programma di test andasse a spostare effettivamente dati sulla cache, dal codice sorgente

sarebbe possibile ricavare anche solo parte dell’algoritmo di replacement, che rappresenta

una parte importante del funzionamento del processore. Questo è il motivo per cui i

reference manual impongono delle pratiche di programmazione senza spiegarne la

motivazione, nascondendo meccanismi interni di più basso livello. A onor di cronaca, tale

tecnica viene applicata da tutti i produttori su qualunque modello: i dispositivi Intel non

risultano essere un’eccezione. Considerazioni di questo tipo sono valide anche per board

molto economiche, come la STMicroelectronics STM32F3, dal costo di 12€ e dotata del

processore a 32 bit ARM® Cortex®-M4 dalla frequenza massima di 72 MHz: nel reference

manual, ad esempio viene indicato che nell’utilizzare il convertitore analogico-digitale una

coppia di bit non può variare contemporaneamente [27], ma deve attraversare uno stadio di

transizione; ciò nasconde meccanismi presenti a più basso livello di cui non si vuole

diffondere i dettagli.

Costi del testing. Il testing è un’attività molto costosa e lo diventa maggiormente

all’aumentare del grado di sicurezza che si vuole raggiungere, che nel caso dei sistemi

safety-critical è la massima possibile. Considerando il gran numero di processori che viene

rilasciato anche solo in un anno, le stringenti richieste del time-to-market e la concorrenza,

è impossibile applicare test così costosi su tutti i processori.

Poca remuneratività dei sistemi safety-critical. Anche se le tecniche di testing fossero

applicate con successo, i ricavi risultanti sarebbero ben inferiori rispetto a quelli di altri

settori. Un processore di successo nell’ambito dei sistemi safety-critical tipicamente

raggiunge una vendita di decine di migliaia di unità, mentre uno presente in uno smartphone

sarà venduto in milioni di esemplari [14]. Ecco perché un produttore tenderà a investire di

Page 48: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

48

più, ad esempio, nel settore mobile che non in quello dei sistemi critici. Alcuni difetti

individuati in Diagnostic Tool e nella sua documentazione possono essere ascritti alla

volontà di risparmiare il più possibile anche solo in termini di tempo impiegato alla stesura

del codice.

4.3 Soluzioni e possibili sviluppi futuri

Nonostante le criticità illustrate precedentemente, il problema del testing dei processori per

sistemi safety-critical può comunque essere risolto, anche nel caso più complesso di CPU

superscalari, in modo da garantire una copertura da fallimenti ragionevolmente elevata. Per

raggiungere questo obiettivo, sono necessari interventi sia da parte del produttore che degli

enti regolatori. Si avverte l’esigenza dell’azione di questi ultimi dal fatto che nessuno degli

standard di larga diffusione prevede un qualsiasi tipo di certificazione o verifica delle

proprietà del processore. La necessità di una verifica accurata del corretto funzionamento

della CPU nei sistemi critici non è assolutamente allarmistica né strumentale a questo testo:

basti pensare a quanto successo con la Floating Point Unit dei primi processori Pentium.

Un difetto nella lookup table per calcoli a virgola mobile, conosciuto da Intel sin da maggio

del 1994 (ma l’azienda decise di non diffondere la notizia), faceva sì che alcune operazioni

a virgola mobile producessero risultati errati. Tale difetto divenne di dominio pubblico

nell’ottobre dello stesso anno, ma solo su segnalazione di Thomas Nicely [28], professore

universitario di Matematica, che si accorse di errori nei calcoli per individuare numeri

primi, che si verificavano solo sui nuovi computer con processori Pentium. Intel si difese

sostenendo che un utente normale avrebbe subito un errore di questo tipo ogni 27000 anni,

ma IBM (azienda concorrente nella produzione di chip) rispose che il tasso di fallimento

era 1 ogni 24 giorni; ulteriori test condotti eseguendo operazioni spesso utilizzate da utenti

comuni si avvicinarono maggiormente a quest’ultima stima, 1 ogni 44 giorni [29]. Alla fine

Intel fu costretta a sostituire i processori difettosi, e anche se solo parte degli acquirenti

esercitarono questa opzione, la perdita fu di circa 475 milioni di dollari. La stessa

architettura soffrì poi di un bug, dovuto ad un difetto di progettazione, noto come “F00F

bug” [30], che alla fine fu risolto mediante accorgimenti a livello di sistema operativo. È

Page 49: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

49

evidente che se questi errori si fossero verificati su un sistema safety-critical, le

conseguenze sarebbero potute essere devastanti, considerando anche il fatto che il

processore era stato immesso sul mercato da più di un anno (Marzo 1993), e c’era quindi

la possibilità che fosse installato su un grande numero di macchine.

Appare evidente come il primo passo per risolvere questo problema sia la creazione di

standard per processori utilizzati nei sistemi critici. Un possibile punto di partenza potrebbe

essere la certificazione proposta in [14], formalizzata mediante Goal Structuring Notation.

Tale proposta mira a determinare l’affidabilità di un processore, partendo da affermazioni

di alto livello, che vengono via via scomposte in proprietà più semplici che possono essere

verificate con test, ad esempio usando un misto tra il testing proposto nel capitolo 2 (per le

componenti del processore) e Diagnostic Tool modificato, in modo da avere anche una

verifica funzionale della CPU.

Il produttore potrebbe poi condurre in proprio gran parte dei test, diffondendo all’ente

preposto solo un ristretto sottoinsieme di informazioni. Come abbiamo visto, il produttore

non vuole diffondere informazioni considerate strategiche; così facendo diminuisce la

copertura dei fallimenti ottenibile da una compagnia di test esterna. Considerato ciò,

potrebbe essere una soluzione efficace quella di assegnare al produttore stesso il compito

del testing del processore, in modo da diffondere all’esterno il minor numero di

informazioni, e comunicare i risultati ottenuti all’autorità competente. Si potrebbe anche

pensare di dividere il testing tra produttore e una compagnia esterna di testing e rating, in

modo che il primo si limiti a testare solamente ciò che implica informazioni riservate (ad

esempio test sulla cache), e la seconda tutti i restanti test (ad esempio operazioni floating

point, generazione e verifica numeri primi, test di set di istruzioni…).

Sarebbe opportuno poi che solo un ridotto e ben definito sottoinsieme di processori

sia utilizzato nelle board. Questo perché esistono un gran numero di varianti dello stesso

processore, ciascuna delle quali differisce per algoritmi di basso livello, architettura o

prestazioni. Tuttavia anche elementi di questo tipo possono introdurre incertezze o nuovi

errori. Inoltre il testing accurato di una CPU richiede tempo e risorse, e quindi non sarebbe

conveniente e applicabile l’applicazione di questo a un gran numero di modelli e varianti.

Page 50: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

50

Ecco perché, per evitare il caos di testing che si avrebbe con la diffusione di board con CPU

simili ma diverse in alcune caratteristiche, sarebbe opportuno mantenerne ben controllato

il numero e la tipologia.

Page 51: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

51

Bibliografia

[1] M. Hinchey, L. Coyle, Evolving Critical Systems: a Research Agenda for Computer-

Based Systems, 2010 17th IEEE International Conference and Workshops on Engineering

of Computer-Based Systems, 2, 22/03/2010

[2] I. Sommerville, Software Engineering, Pearson, 2015

[3] L. Rierson, Developing Safety-Critical Software: A Practical Guide for Aviation

Software and DO-178C Compliance, CRC Press, 2013

[4] J. Boulanger, CENELEC 50128 and IEC 62279 Standards, John Wiley & Sons, 2015

[5] IEEE GlobalSpec, http://standards.globalspec.com/std/1272146/cenelec-en-50126-1,

23/12/2016

[6] British Standards Institution, The specification and demonstration of Reliability,

Availability, Maintainability and Safety (RAMS), BSI, 2007

[7] IEEE GlobalSpec, http://standards.globalspec.com/std/1678027/cenelec-en-50128,

23/12/2016

[8] J. Rodriguez, 20th International Conference on Reliable Software Technologies -

Ada-Europe 2015, 2015

[9] IEEE GlobalSpec, http://standards.globalspec.com/std/1266373/cenelec-en-50129,

23/12/2016

[10] IEEE GlobalSpec, http://standards.globalspec.com/std/1272813/cenelec-en-50155,

23/12/2016

[11] IEEE GlobalSpec, http://standards.globalspec.com/std/1285055/cenelec-en-50159,

23/12/2016

[12] IEEE GlobalSpec, http://standards.globalspec.com/std/1271136/cenelec-en-50159-1,

23/12/2016

Page 52: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

52

[13] N. Kranitis, A. Paschalis D. Gizopoulos e Y. Zorian, Effective Software Self-Test

Methodology for Processor Cores, Proceedings of the 2002 Design, Automation and Test

in Europe Conference and Exhibition, 592, 04/03/2002

[14] I.Bate, P. Conmy, T.Kelly e J.McDermid, Use of Modern Processors in

Safety-Critical Applications, The Computer Journal, 44, 531-543, 13/04/2001

[15] I. Moir, A. Seabridge e M. Jukes, Civil Avionics Systems, John Wiley & Sons, 2013

[16] Ministero delle Infrastrutture e dei Trasporti,

http://www.mit.gov.it/mit/mop_all.php?p_id=05338 , 20/12/2016

[17] L. Chen, S. Dey, P. Sanchez, K. Sekar e Y. Chen, Embedded hardware and software

self-testing methodologies for processor cores, Design Automation Conference, 2000.

Proceedings 2000, 625, 05/06/2000

[18] C. Stroud, A Designer’s Guide to Built-In Self-Test, Springer, 2002

[19] Intel, https://downloadcenter.intel.com/it/download/19792/Intel-Processor-

Diagnostic-Tool, 08/12/2016

[20] Intel, Intel® Processor Identification and the CPUID Instruction Application Note

485, Agosto 2009

[21] Intel, https://communities.intel.com/thread/43687, 17/12/2016

[22] Microsoft Developer Network, https://msdn.microsoft.com/it-

it/library/windows/desktop/ms683212(v=vs.85).aspx, 15/12/2016

[23] Microsoft Developer Network, https://msdn.microsoft.com/it-

it/library/windows/desktop/aa363216(v=vs.85).aspx , 15/12/2016

[24] The Linux Documentation Project, http://tldp.org/LDP/tlk/dd/pci.html, 15/12/2016

[25] Intel, The Intel® Processor Diagnostic Tool – Help Documentation, 27, 2015

[26] Intel, http://www.intel.it/content/www/it/it/support/processors/000005597.html,

19/12/2016

[27] STMicroelectronics, RM0316 Reference manual, Marzo 2013

[28] Some Results of Research in Computational Number Theory,

http://www.trnicely.net/pentbug/pentbug.html, 23/12/2016

[29] Los Angeles Times, http://articles.latimes.com/1994-12-17/business/fi-

Page 53: Tecniche e strumenti di testing per processori superscalari · 3.2.8 MMXSSE ... Fail-operational systems: il sistema deve continuare ad operare anche se la componente di controllo

53

9948_1_error-rate , 23/12/2016

[30] Dartmouth College,

http://www.cs.dartmouth.edu/~sergey/cs108/2009/F00FBug.html, 23/12/2016