-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add latency estimations to simulator #21
base: master
Are you sure you want to change the base?
Changes from 3 commits
fa4016d
8f403b8
3141ac5
fe3d72d
22cc30c
b46f6d2
770f2da
de70c2c
4b563b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import copy | ||
import os.path | ||
import csv | ||
|
||
OPERATIONS_MEMORY_ACCESS = ["LWD", "LWI", "SWD","SWI"] | ||
|
||
def load_operation_characterization(operation_mapping, characterization_type): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why take operation mapping as a parameter? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed ✔️ |
||
script_dir = os.path.dirname(os.path.abspath(__file__)) | ||
csv_file_path = os.path.join(script_dir, 'operation_characterization.csv') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we leave the characterization file as a parameter? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✔️ |
||
|
||
with open(csv_file_path, 'r') as csvfile: | ||
reader = csv.reader(csvfile) | ||
for row in reader: | ||
if not row: | ||
continue | ||
if row[0].startswith('#'): | ||
current_section = row[0].strip('# ') | ||
continue | ||
if current_section == f'operation_{characterization_type}_mapping': | ||
if len(row) == 3: | ||
key_type, value_type = int, float | ||
operation, key, value = row | ||
key = key_type(key) | ||
value = value_type(value) | ||
if operation not in operation_mapping: | ||
operation_mapping[operation] = {} | ||
operation_mapping[operation][key] = value | ||
elif len(row) == 2: | ||
key_type, value_type = int, int | ||
operation, key = row | ||
key = key_type(key) | ||
if operation not in operation_mapping: | ||
operation_mapping[operation] = key | ||
else: | ||
continue | ||
return operation_mapping | ||
|
||
def get_latency_cc(self): | ||
from cgra import N_ROWS, N_COLS | ||
self.max_latency_instr = None | ||
mem_latency_cc = 0 | ||
for r in range(N_ROWS): | ||
for c in range(N_COLS): | ||
if self.max_latency_instr is None or self.cells[r][c].latency_cc > self.max_latency_instr.latency_cc: | ||
self.max_latency_instr = self.cells[r][c] | ||
if self.cells[r][c].op in OPERATIONS_MEMORY_ACCESS: | ||
mem_latency_cc += 1 | ||
# A memory access to a memory bank has a 2-cycle overhead, | ||
# plus 1 additional cycle per PE trying to access it. | ||
if mem_latency_cc >= 1: | ||
mem_latency_cc += 1 | ||
self.max_latency_instr.latency_cc = max(self.max_latency_instr.latency_cc, mem_latency_cc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find it a little unhappy that this logic has to be hardcoded. This is easy now, but when we speak about the INTERLEAVED BUS you will not want to change the code to switch from one to other. What about this other approach:
Here you kind of embed the logic in the CSV and simplify the logic in the code, so if you want to test different architectures you dont need to modify the code. The example from above is the different bus topologies you already encountered (dont take this as is, as I could be wrong) The idea is that you encode in the different columns different latency patterns and how they are affected by operations of the same type. For example, I'm not saying DO IT LIKE THIS ... but this kind of spirit that you will not want to change the code every time. It's something one day we will also do for the instruction operations to make the logic independent of the simulator so we can test different architecture changes without modifying the code. BTW.. the passion for not modifying the code is because we would like to have e.g. 20 different architectures and test which is the best. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, given how you implemented the fetch of the values, in the same CSV we could have different implementations:
|
||
if (self.exit): | ||
if (self.max_latency_instr.latency_cc > 2): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this tho? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -The "max" function is used to only retain the largest operation (ie: between 3CC multiplication and only one 2CC memory operation, conserve the SMUL) |
||
self.max_latency_instr.latency_cc += 1 | ||
|
||
self.max_latency_instr.instr2exec = self.instr2exec | ||
self.instr_latency_cc.append(copy.copy(self.max_latency_instr)) | ||
self.total_latency_cc += self.instr_latency_cc[-1].latency_cc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's all this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First line: we need the current CGRA-cycle number as well as that of the instruction being executed (instr2exec) |
||
|
||
def display_characterization(cgra): | ||
print("Longest instructions per cycle:\n") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. with "cycle" you mean "CGRA-cycle" (i.e. the execution of an instruction)?
Instead of forcing the user to see all the time everything There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, I'm going to do this |
||
print("{:<8} {:<25} {:<10}".format("Cycle", "Instruction", "Latency (CC)")) | ||
for index, item in enumerate(cgra.instr_latency_cc): | ||
print("{:<2} {:<6} {:<25} {:<10}".format(index + 1, f'({item.instr2exec})', item.instr, item.latency_cc)) | ||
print("\nTotal latency for all instructions:", cgra.total_latency_cc, "CC") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# operation_latency_cc_mapping | ||
NOP,1 | ||
EXIT,2 | ||
SADD,1 | ||
SSUB,1 | ||
SLT,1 | ||
SRT,1 | ||
SRA,1 | ||
LAND,1 | ||
LOR,1 | ||
LXOR,1 | ||
LNAND,1 | ||
LNOR,1 | ||
LXNOR,1 | ||
BSFA,1 | ||
BZFA,1 | ||
BEQ,1 | ||
BNE,1 | ||
BLT,1 | ||
BGE,1 | ||
JUMP,1 | ||
LWD,2 | ||
SWD,2 | ||
LWI,2 | ||
SWI,2 | ||
SMUL,3 | ||
FXPMUL,3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move the latency-related operations to a separate module
latency.py
?It is unclear to me when this code is gonna execute (when loading the module probably). I would rather have a
latency_load_characterization( filename )
function, so we could actually have more than one possible characterization (for example, for the case where you wanna test different scenarios.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I added a function that can eventually be reused for other characterizations