1) Βασικές παράμετροι επεξεργαστή / Υποσύστημα μνημών cache
Ανοίγοντας το config.ini:
- L1--dcache:
- Μέγεθος : 64KB
- associativity : 2
- cache_line_size : 64 Bytes
- L1--icache:
- Μέγεθος : 32KB
- associativity : 2
- cache_line_size : 64 Bytes
- L2--icache:
- Μέγεθος : 2MB
- associativity : 8
- cache_line_size : 64 Bytes
2) Αποτελέσματα απο κάθε benchmark
-
-- Benchmark specbzip
Από το αρχείο stats.txt:
--Χρόνος εκτέλεσης:- sim_seconds 0.083654 # Number of seconds simulated
--Μέσο CPI:
- system.cpu.cpi 1.673085 # CPI: cycles per instruction
--Miss rate
- L1 cache:
- icache
line332: system.cpu.icache.overall_miss_rate::total 0.000075 # miss rate for overall accesses
- dcache
system.cpu.dcache.overall_miss_rate::total 0.014312 # miss rate for overall accesses
- L2 cache
system.l2.overall_miss_rate::total 0.295247 # miss rate for overall accesses
-
-- Benchmark spechmmer
Από το αρχείο stats.txt:
--Χρόνος εκτέλεσης:- sim_seconds 0.059390 # Number of seconds simulated
--Μέσο CPI:
- system.cpu.cpi 1.187803 # CPI: cycles per instruction
--Miss rate
- L1 cache:
- icache
system.cpu.icache.overall_miss_rate::total 0.000212 # miss rate for overall accesses
- dcache
system.cpu.dcache.overall_miss_rate::total 0.001628 # miss rate for overall accesses
- L2 cache
system.l2.overall_miss_rate::total 0.078296 # miss rate for overall accesses
-
-- Benchmark speclibm
Από το αρχείο stats.txt:
--Χρόνος εκτέλεσης:- sim_seconds 0.174763 # Number of seconds simulated
--Μέσο CPI:
- system.cpu.cpi 3.495270 # CPI: cycles per instruction
--Miss rate
- L1 cache:
- icache
system.cpu.icache.overall_miss_rate::total 0.000095 # miss rate for overall accesses
- dcache
system.cpu.dcache.overall_miss_rate::total 0.060972 # miss rate for overall accesses
- L2 cache
system.l2.overall_miss_rate::total 0.999940 # miss rate for overall accesses
-
-- Benchmark specmcf
Από το αρχείο stats.txt:
--Χρόνος εκτέλεσης:- sim_seconds 0.062553 # Number of seconds simulated
--Μέσο CPI:
- system.cpu.cpi 1.251067 # CPI: cycles per instruction
--Miss rate
- L1 cache:
- icache
system.cpu.icache.overall_miss_rate::total 0.019032 # miss rate for overall accesses
- dcache
system.cpu.dcache.overall_miss_rate::total 0.002062 # miss rate for overall accesses
- L2 cache
system.l2.overall_miss_rate::total 0.067668 # miss rate for overall accesses
-
-- Benchmark specsjeng
Από το αρχείο stats.txt:
--Χρόνος εκτέλεσης:- sim_seconds 0.513823 # Number of seconds simulated
--Μέσο CPI:
- system.cpu.cpi 10.276466 # CPI: cycles per instruction
--Miss rate
- L1 cache:
- icache
system.cpu.icache.overall_miss_rate::total 0.000020 # miss rate for overall accesses
- dcache
system.cpu.dcache.overall_miss_rate::total 0.121831 # miss rate for overall accesses
- L2 cache
system.l2.overall_miss_rate::total 0.999978 # miss rate for overall accesses
3)Benchmarks cpu_clock = 2Ghz, 1Ghz
Benchmarks για cpu clock 2Ghz
απο το stats.txtsystem.clk_domain.clock 1000 # Clock period in ticks system.cpu_clk_domain.clock 500 # Clock period in ticks
από το config.json
"system":{ ... "clk_domain": { "type": "SrcClockDomain", "cxx_class": "SrcClockDomain", "name": "clk_domain", "path": "system.clk_domain", "clock": [ 1000 ] }
"cpu_clk_domain": { "type": "SrcClockDomain", "cxx_class": "SrcClockDomain", "name": "cpu_clk_domain", "path": "system.cpu_clk_domain", "clock": [ 500 ]
Benchmarks για cpu clock 1Ghz
απο το stats.txtsystem.clk_domain.clock 1000 # Clock period in ticks system.cpu_clk_domain.clock 1000 # Clock period in ticks
από το config.json
"system":{ ... "clk_domain": { "type": "SrcClockDomain", "cxx_class": "SrcClockDomain", "name": "clk_domain", "path": "system.clk_domain", "clock": [ 1000 ] }
"cpu_clk_domain": { "type": "SrcClockDomain", "cxx_class": "SrcClockDomain", "name": "cpu_clk_domain", "path": "system.cpu_clk_domain", "clock": [ 1000 ]
To system.clk_domain.clock δηλαδή το ρολόι συγχρονισμού του συστήματος είναι ίδιο και στις δύο περιπτώσεις και ίσο με 1000 δηλαδή 1 GHz.
Το default system.cpu_clk_domain δηλαδή το ρολόι χρονισμού της CPU είναι 500 ή 2 GHz. Το ρολόι αυτό ρυθμίζει το ρολόι του CPU και των μονάδων επεξεργασίας του, δηλαδή των L1 Data και Instruction cache, της L2 cache.
Αν προσθέσουμε άλλον έναν επεξεργαστή η συχνότητα θα είναι αυτή που δηλώνεται στο αρχείο se.py, δηλαδή 1 GHz για το system.clk_domain.clock και 2 GHz για το system.cpu_clk_domain , εκτός αν ορίσουμε διαφορετική συχνότητα με τις εντολές --sys-clock = # και --cpu-clock = # αντίστοιχα
Για τους χρόνους εκτέλεσης:
-
specbzip
1GHz: sim_seconds 0.160359 # Number of seconds simulated
2GHz: sim_seconds 0.083654 # Number of seconds simulated
0.160359 ÷ 0.083654 = 1,9169
Ο λόγος αυτός είναι πολύ κοντά στο τέλειο scaling, γιατί για το συγκεκριμένο benchmark το ρολόι του επεξεργαστή παίζει τον καθοριστικό παράγοντα και όχι τόσο οι ταχύτητες απόκρισης των μνημών.
-
spechmmer
1GHz: sim_seconds 0.118517 # Number of seconds simulated
2GHz: sim_seconds 0.059390 # Number of seconds simulated
0.118517 ÷ 0.059390 = 1,995571645
Πρόκειται για τελειο scaling, γιατί για το συγκεκριμένο benchmark το ρολόι του επεξεργαστή παίζει τον καθοριστικό παράγοντα και όχι τόσο οι ταχύτητες απόκρισης των μνημών.
-
specmcf
1GHz: sim_seconds 0.123107# Number of seconds simulated
2GHz: sim_seconds 0.062553 # Number of seconds simulated
0.123107 ÷ 0.062553 = 1,968043099
Ο λόγος αυτός είναι πολύ κοντά στο τέλειο scaling, γιατί για το συγκεκριμένο benchmark το ρολόι του επεξεργαστή παίζει τον καθοριστικό παράγοντα και όχι τόσο οι ταχύτητες απόκρισης των μνημών.
-
specsjeng
1GHz: sim_seconds 0.705640 # Number of seconds simulated
2GHz: sim_seconds 0.513823 # Number of seconds simulated
0.705640 ÷ 0.513823 = 1,373313378
Ο λόγος απέχει αρκετά από το τέλειο scaling καθώς εδώ(συγκεκριμένο benchmark) είναι καθοριστικός και ο ρόλος των αποκρίσεων των μνημών cache (προσβάσεις στην μνήμη).
-
speclibm
1GHz: sim_seconds 0.262262 # Number of seconds simulated
2GHz: sim_seconds 0.174763 # Number of seconds simulated
0.262262 ÷ 0.174763 = 1,500672339
Ο λόγος απέχει αρκετά από το τέλειο scaling καθώς εδώ(συγκεκριμένο benchmark) είναι καθοριστικός και ο ρόλος των αποκρίσεων των μνημών cache (προσβάσεις στην μνήμη).
Μετά από τέστ που τρέξαμε προβήκαμε στις εξής βελτιστοποιήσεις(σειρά)
1) Η πρώτη βελτιστοποίηση που κάναμε αφορούσε το cache line size == block size κρατώντας τα υπόλοιπα στις default τιμές τους.
l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specbzip | specmcf | specsjeng | spechmmer | speclibm |
---|---|---|---|---|---|---|---|---|---|---|---|
64KB | 32KB | 2MB | 2 | 2 | 8 | 64B | 1.603595 | 1.23264 | 7.056 | 1.18517 | 2.623 |
64KB | 32KB | 2MB | 2 | 2 | 8 | 32B | 1.7078 | 1.21456 | 11.666 | 1.19194 | 3.921 |
64KB | 32KB | 2MB | 2 | 2 | 8 | 128B | 1.5966 | 1.23605 | 4.985 | 1.18016 | 1.990 |
64KB | 32KB | 2MB | 2 | 2 | 8 | 256B | 1.5945 | 1.24091 | 3.715 | 1.18106 | 1.654 |
2) Με βάση το best case cachelinesize-cpi εκτελούμε τα παρακάτω πειράματα
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | speclibm |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 256 | 1.654968 |
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 256 | 1.654777 |
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 256 | 1.654405 |
D | 128KB | 128KB | 4MB | 2 | 2 | 8 | 256 | 1.653662 |
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | spechmmer |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 128 | 1.179634 |
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 128 | 1.178092 |
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 128 | 1.178092 |
D | 128KB | 128KB | 4MB | 2 | 2 | 8 | 128 | 1.178092 |
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specsjeng |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 256 | 3.715711 |
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 256 | 3.715872 |
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 256 | 3.715443 |
D | 128KB | 128KB | 4MB | 2 | 2 | 8 | 256 | 3.714662 |
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specbzip |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 256 | 1.647000 |
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 256 | 1.571640 |
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 256 | 1.557965 |
D | 128KB | 128KB | 4MB | 2 | 2 | 8 | 256 | 1.550634 |
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specmcf |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 32 | 1.146603 |
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 32 | 1.145850 |
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 32 | 1.144656 |
D | 128KB | 128KB | 4MB | 2 | 2 | 8 | 32 | 1.144551 |
Συνεχίζουμε με το μικρότερο δυνατό cpi, που μας δίνουν οι περιπτώσεις A,B,C,D (που αφορούν μεγέθη μνημών) και προσπαθούμε για περαιτέρω βελτίωση του cpi αλλάζοντας το associativity των μνημών cache. Οπότε εκτελούμε τα παρακάτω πειράματα Α1,Β1,C1,D1 για τη καθεμία βέλτιστη περίπτωση αντίστοιχα.
Για το benchmark specbzip, για το πείραμα type D (l1_dsize = l1_isize = 128KB, l2_size = 4MB) :
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specbzip |
---|---|---|---|---|---|---|---|---|
A1 | 128KB | 128KB | 4MB | 1 | 1 | 8 | 256 | 1.569167 |
B1 | 128KB | 128KB | 4MB | 4 | 4 | 8 | 256 | 1.545340 |
C1 | 128KB | 128KB | 4MB | 8 | 8 | 8 | 256 | 1.539940 |
D1 | 128KB | 128KB | 4MB | 8 | 8 | 16 | 256 | 1.539524 |
Για το benchmark spechmmer, για το πείραμα type B (l1_dsize = l1_isize = 128KB, l2_size = 1MB) :
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | spechmmer |
---|---|---|---|---|---|---|---|---|
A1 | 128KB | 128KB | 1MB | 1 | 1 | 8 | 128 | 1.184147 |
B1 | 128KB | 128KB | 1MB | 4 | 4 | 8 | 128 | 1.177829 |
C1 | 128KB | 128KB | 1MB | 8 | 8 | 8 | 128 | 1.177692 |
D1 | 128KB | 128KB | 1MB | 8 | 8 | 16 | 128 | 1.177692 |
Για το benchmark specmcf, για το πείραμα type D (l1_dsize = l1_isize = 128KB, l2_size = 4MB) :
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specmcf |
---|---|---|---|---|---|---|---|---|
A1 | 128KB | 128KB | 4MB | 1 | 1 | 8 | 32 | 1.145174 |
B1 | 128KB | 128KB | 4MB | 4 | 4 | 8 | 32 | 1.144551 |
C1 | 128KB | 128KB | 4MB | 8 | 8 | 8 | 32 | 1.144551 |
D1 | 128KB | 128KB | 4MB | 8 | 8 | 16 | 32 | 1.144551 |
Για το benchmark specsjeng, για το πείραμα type D (l1_dsize = l1_isize = 128KB, l2_size = 4MB) :
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specsjeng |
---|---|---|---|---|---|---|---|---|
A1 | 128KB | 128KB | 4MB | 1 | 1 | 8 | 256 | 3.714885 |
B1 | 128KB | 128KB | 4MB | 4 | 4 | 8 | 256 | 3.714674 |
C1 | 128KB | 128KB | 4MB | 8 | 8 | 8 | 256 | 3.714681 |
D1 | 128KB | 128KB | 4MB | 8 | 8 | 16 | 256 | 3.714669 |
Για το benchmark speclibm, για το πείραμα type D (l1_dsize = l1_isize = 128KB, l2_size = 4MB) :
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | speclibm |
---|---|---|---|---|---|---|---|---|
A1 | 128KB | 128KB | 4MB | 1 | 1 | 8 | 256 | 1.672409 |
B1 | 128KB | 128KB | 4MB | 4 | 4 | 8 | 256 | 1.653656 |
C1 | 128KB | 128KB | 4MB | 8 | 8 | 8 | 256 | 1.653656 |
D1 | 128KB | 128KB | 4MB | 8 | 8 | 16 | 256 | 1.653656 |
cost = ((l1i_size+l1d_size)/KB)*0.8 + ((l2_size)/KB)0.05 + (l1i_assoc+l1d_assoc+l2_assoc)*2 + ((cache_line_size)/32B)*5
Best case CPI cost values for each benchmark:
- specbzip
- cost = 508.8 (D1 case)
- spechmmer
- cost = 322.8 (C1 case)
- specsjeng
- cost = 508.8 (D1 case)
- specmcf
- cost = 441.8 (B1 case)
- speclibm
- cost = 476.8 (B1 case)
Best Deal
specbzip
Οσον αφορά αυτό το benchmark μπορούμε να δουμε το case C
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specbzip |
---|---|---|---|---|---|---|---|---|
C | 128KB | 128KB | 2MB | 2 | 2 | 8 | 256 | 1.557965 |
. Η επιλογή αυτή έχει κόστος :
- cost = 368.8 , δηλαδή μειώσαμε το κόστος κατά 140 και έχουμε αύξηση του cpi της τάξης του 0,01 ( lowest cpi = cpi_D1 = 1.539524 )
spechmmer
Οσον αφορά αυτό το benchmark μπορούμε να δουμε το case A
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | spechmmer |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 128 | 1.179634 |
. Η επιλογή αυτή έχει κόστος :
- cost = 172 , δηλαδή μειώσαμε το κόστος κατά 150.8 και έχουμε αύξηση του cpi της τάξης του 0,001 ( lowest cpi = cpi_C1 = 1.177692 )
specsjeng
Οσον αφορά αυτό το benchmark μπορούμε να δουμε το case A
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specsjeng |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 256 | 3.715711 |
. Η επιλογή αυτή έχει κόστος :
- cost = 192 , δηλαδή μειώσαμε το κόστος κατά 316.8 και έχουμε αύξηση του cpi της τάξης του 0,001 ( lowest cpi = cpi_D1 = 3.714669 )
specmcf
Οσον αφορά αυτό το benchmark μπορούμε να δουμε το case B
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | specmcf |
---|---|---|---|---|---|---|---|---|
B | 128KB | 128KB | 1MB | 2 | 2 | 8 | 32 | 1.145850 |
. Η επιλογή αυτή έχει κόστος :
- cost = 283.8 , δηλαδή μειώσαμε το κόστος κατά 158 και έχουμε αύξηση του cpi της τάξης του 0,001 ( lowest cpi = cpi_B1 = 1.144551 )
speclibm
Οσον αφορά αυτό το benchmark μπορούμε να δουμε το case A
TEST_TYPE | l1_dsize | l1_isize | l2_size | l1d_assoc | l1i_assoc | l2_assoc | cacheline_size | speclibm |
---|---|---|---|---|---|---|---|---|
A | 64KB | 64KB | 512KB | 2 | 2 | 8 | 256 | 1.654968 |
. Η επιλογή αυτή έχει κόστος :
- cost = 283.8 , δηλαδή μειώσαμε το κόστος κατά 158 και έχουμε αύξηση του cpi της τάξης του 0,001 ( lowest cpi = cpi_B1 = 1.653656 )
- Βλέποντας τα best deals για κάθε περίπτωση αποδεικνύουμε τον καθοριστικό ρόλο στην απόδoση που παίζει το cache line size και όχι τόσο τα υπόλοιπα στοιχεία. Έτσι, επιλέγουμε σε κάθε αρχιτκτονική να χρησιμοποιήσουμε τα ελάχιστα δυνατά μεγέθη μνημών (που είναι και τα πιο ακριβά) θυσιάζοντας κάτι από την απόδοση.
- Η συνάρτηση κόστους μας, ίσως τιμωρεί λίγο παραπάνω μεγάλες σε μέγεθος μνήμες l1,l2 έχοντας υψηλό συντελεστή κόστους. Τα υπόλοιπα στοιχεία ( associativity, cache block size) τα εντάξαμε ώστε τα κόστη τους να μην είναι συγκρίσιμα με το κόστος ολόκληρης της μνήμης.
- https://en.wikipedia.org/wiki/CPU_cache
- https://cseweb.ucsd.edu/classes/fa99/cse240/cache2.pdf?fbclid=IwAR2CIiuWHeyoyQ5xyfjTcIr7CUlEooAXJbLGmWtG5eCOnD-b7NhFFXcpcso
- http://csillustrated.berkeley.edu/PDFs/handouts/cache-3-associativity-handout.pdf?fbclid=IwAR1CmHsHyjCZAB8eAHSpH03UPlbcoyC67JucFyJzXfcb11bknob9_glnA08
Η εργασία μας έβαλε στην λογική του αρχιτέκτονα επεξεργαστών, μας έφερε αντιμέτωπους με ζητήματα που προκύπτουν σχετικά με την σχεδίαση, την απόδοση και το κόστος του υποσυστήματος μνημών του επεξεργαστή.
Είδαμε οτι δεν υπάρχει κάποια συγκεκριμένη μέθοδος στην επίλυση των παραπάνω ζητημάτων αλλά έπρεπε να εξασκήσουμε την φαντασία μας και να κάνουμε πολλές δοκιμές (οι οποίες ήταν χρονοβόρες, καθώς τρέχαμε σε προσομοιωτή).
Στο εργαστήριο 2 γίνεται εφαρμογή θεωρίας σε πρακτικό/σχεδιαστικό επίπεδο.
Παρατηρήσεις:
- Υπήρξε ένα θέμα με τον cross-compiler gcc-arm λόγω του python version που λύθηκε απο τους αρμόδιους.
- Στο πρώτο βήμα, και συγκεκριμένα στο τρίτο ερώτημα, έπρεπε να ζητείται να τρέξουμε --cpu-clock=1Ghz και όχι 2GHz, διότι 2 Ghz είναι η default τιμή.