mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-04 10:10:08 +01:00
enhanced dynamic combine of LD and arithmetic instr
This commit is contained in:
@@ -417,7 +417,19 @@ instruction_forms:
|
|||||||
scale: 1
|
scale: 1
|
||||||
- class: register
|
- class: register
|
||||||
name: xmm
|
name: xmm
|
||||||
throughput: 1.0
|
throughput: 0.5
|
||||||
|
latency: 4.0 # 1*p23+1*p2D3D
|
||||||
|
port_pressure: [[1, '23'], [1, [2D, 3D]]]
|
||||||
|
- name: vmovapd
|
||||||
|
operands:
|
||||||
|
- class: memory
|
||||||
|
base: gpr
|
||||||
|
offset: ~
|
||||||
|
index: gpr
|
||||||
|
scale: 1
|
||||||
|
- class: register
|
||||||
|
name: ymm
|
||||||
|
throughput: 0.5
|
||||||
latency: 4.0 # 1*p23+1*p2D3D
|
latency: 4.0 # 1*p23+1*p2D3D
|
||||||
port_pressure: [[1, '23'], [1, [2D, 3D]]]
|
port_pressure: [[1, '23'], [1, [2D, 3D]]]
|
||||||
- name: vmovapd
|
- name: vmovapd
|
||||||
@@ -429,7 +441,7 @@ instruction_forms:
|
|||||||
scale: 1
|
scale: 1
|
||||||
- class: register
|
- class: register
|
||||||
name: ymm
|
name: ymm
|
||||||
throughput: 1.0
|
throughput: 0.5
|
||||||
latency: 4.0 # 1*p23+1*p2D3D
|
latency: 4.0 # 1*p23+1*p2D3D
|
||||||
port_pressure: [[1, '23'], [1, [2D, 3D]]]
|
port_pressure: [[1, '23'], [1, [2D, 3D]]]
|
||||||
- name: vmovapd
|
- name: vmovapd
|
||||||
@@ -441,7 +453,7 @@ instruction_forms:
|
|||||||
offset: ~
|
offset: ~
|
||||||
index: gpr
|
index: gpr
|
||||||
scale: 1
|
scale: 1
|
||||||
throughput: 1.0
|
throughput: 0.5
|
||||||
latency: 4.0 # 1*p23+1*p4
|
latency: 4.0 # 1*p23+1*p4
|
||||||
port_pressure: [[1, '23'], [1, '4']]
|
port_pressure: [[1, '23'], [1, '4']]
|
||||||
- name: vmovapd
|
- name: vmovapd
|
||||||
|
|||||||
@@ -2632,6 +2632,13 @@ instruction_forms:
|
|||||||
port_pressure: [[10, '0'], [4, '01'], [3, '015'], [1, '05'], [11, '1'], [1, '15'], [2, '23'], [1, '4'], [25, '5']]
|
port_pressure: [[10, '0'], [4, '01'], [3, '015'], [1, '05'], [11, '1'], [1, '15'], [2, '23'], [1, '4'], [25, '5']]
|
||||||
throughput: 27.0
|
throughput: 27.0
|
||||||
uops: 58
|
uops: 58
|
||||||
|
- name: JA
|
||||||
|
operands:
|
||||||
|
- class: identifier
|
||||||
|
latency: 0
|
||||||
|
port_pressure: []
|
||||||
|
throughput: 0.0
|
||||||
|
uops: 1
|
||||||
- name: JNE
|
- name: JNE
|
||||||
operands:
|
operands:
|
||||||
- class: identifier
|
- class: identifier
|
||||||
@@ -4196,6 +4203,16 @@ instruction_forms:
|
|||||||
port_pressure: [[1, '015']]
|
port_pressure: [[1, '015']]
|
||||||
throughput: 0.3333333333333333
|
throughput: 0.3333333333333333
|
||||||
uops: 1
|
uops: 1
|
||||||
|
- name: ADD
|
||||||
|
operands:
|
||||||
|
- class: register
|
||||||
|
name: gpr
|
||||||
|
- class: register
|
||||||
|
name: gpr
|
||||||
|
latency: 1
|
||||||
|
port_pressure: [[1, '015']]
|
||||||
|
throughput: 0.3333333333333333
|
||||||
|
uops: 1
|
||||||
- name: REX ADD
|
- name: REX ADD
|
||||||
operands:
|
operands:
|
||||||
- class: immediate
|
- class: immediate
|
||||||
|
|||||||
@@ -135,39 +135,9 @@ class ArchSemantics(ISASemantics):
|
|||||||
)
|
)
|
||||||
if instruction_data:
|
if instruction_data:
|
||||||
# instruction form in DB
|
# instruction form in DB
|
||||||
throughput = instruction_data['throughput']
|
latency_wo_load = self._handle_instruction_found(
|
||||||
port_pressure = self._machine_model.average_port_pressure(
|
instruction_data, port_number, instruction_form, flags
|
||||||
instruction_data['port_pressure']
|
|
||||||
)
|
)
|
||||||
instruction_form['port_uops'] = instruction_data['port_pressure']
|
|
||||||
try:
|
|
||||||
assert isinstance(port_pressure, list)
|
|
||||||
assert len(port_pressure) == port_number
|
|
||||||
instruction_form['port_pressure'] = port_pressure
|
|
||||||
if sum(port_pressure) == 0 and throughput is not None:
|
|
||||||
# port pressure on all ports 0 --> not bound to a port
|
|
||||||
flags.append(INSTR_FLAGS.NOT_BOUND)
|
|
||||||
except AssertionError:
|
|
||||||
warnings.warn(
|
|
||||||
'Port pressure could not be imported correctly from database. '
|
|
||||||
+ 'Please check entry for:\n {}'.format(instruction_form)
|
|
||||||
)
|
|
||||||
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
|
|
||||||
instruction_form['port_uops'] = []
|
|
||||||
flags.append(INSTR_FLAGS.TP_UNKWN)
|
|
||||||
if throughput is None:
|
|
||||||
# assume 0 cy and mark as unknown
|
|
||||||
throughput = 0.0
|
|
||||||
flags.append(INSTR_FLAGS.TP_UNKWN)
|
|
||||||
latency = instruction_data['latency']
|
|
||||||
latency_wo_load = latency
|
|
||||||
if latency is None:
|
|
||||||
# assume 0 cy and mark as unknown
|
|
||||||
latency = 0.0
|
|
||||||
latency_wo_load = latency
|
|
||||||
flags.append(INSTR_FLAGS.LT_UNKWN)
|
|
||||||
if INSTR_FLAGS.HAS_LD in instruction_form['flags']:
|
|
||||||
flags.append(INSTR_FLAGS.LD)
|
|
||||||
else:
|
else:
|
||||||
# instruction could not be found in DB
|
# instruction could not be found in DB
|
||||||
assign_unknown = True
|
assign_unknown = True
|
||||||
@@ -217,9 +187,9 @@ class ArchSemantics(ISASemantics):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
instruction_form['port_uops'] = list(chain(
|
instruction_form['port_uops'] = list(
|
||||||
instruction_data_reg['port_pressure'], load_port_uops
|
chain(instruction_data_reg['port_pressure'], load_port_uops)
|
||||||
))
|
)
|
||||||
|
|
||||||
if assign_unknown:
|
if assign_unknown:
|
||||||
# --> mark as unknown and assume 0 cy for latency/throughput
|
# --> mark as unknown and assume 0 cy for latency/throughput
|
||||||
@@ -242,12 +212,51 @@ class ArchSemantics(ISASemantics):
|
|||||||
instruction_form['latency_cp'] = 0
|
instruction_form['latency_cp'] = 0
|
||||||
instruction_form['latency_lcd'] = 0
|
instruction_form['latency_lcd'] = 0
|
||||||
|
|
||||||
def substitute_mem_address(self, operands):
|
def _handle_instruction_found(self, instruction_data, port_number, instruction_form, flags):
|
||||||
reg_ops = [op for op in operands if 'register' in op]
|
throughput = instruction_data['throughput']
|
||||||
reg_type = self._parser.get_reg_type(reg_ops[0]['register'])
|
port_pressure = self._machine_model.average_port_pressure(
|
||||||
return [self.convert_mem_to_reg(op, reg_type) for op in operands]
|
instruction_data['port_pressure']
|
||||||
|
)
|
||||||
|
instruction_form['port_uops'] = instruction_data['port_pressure']
|
||||||
|
try:
|
||||||
|
assert isinstance(port_pressure, list)
|
||||||
|
assert len(port_pressure) == port_number
|
||||||
|
instruction_form['port_pressure'] = port_pressure
|
||||||
|
if sum(port_pressure) == 0 and throughput is not None:
|
||||||
|
# port pressure on all ports 0 --> not bound to a port
|
||||||
|
flags.append(INSTR_FLAGS.NOT_BOUND)
|
||||||
|
except AssertionError:
|
||||||
|
warnings.warn(
|
||||||
|
'Port pressure could not be imported correctly from database. '
|
||||||
|
+ 'Please check entry for:\n {}'.format(instruction_form)
|
||||||
|
)
|
||||||
|
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
|
||||||
|
instruction_form['port_uops'] = []
|
||||||
|
flags.append(INSTR_FLAGS.TP_UNKWN)
|
||||||
|
if throughput is None:
|
||||||
|
# assume 0 cy and mark as unknown
|
||||||
|
throughput = 0.0
|
||||||
|
flags.append(INSTR_FLAGS.TP_UNKWN)
|
||||||
|
latency = instruction_data['latency']
|
||||||
|
latency_wo_load = latency
|
||||||
|
if latency is None:
|
||||||
|
# assume 0 cy and mark as unknown
|
||||||
|
latency = 0.0
|
||||||
|
latency_wo_load = latency
|
||||||
|
flags.append(INSTR_FLAGS.LT_UNKWN)
|
||||||
|
if INSTR_FLAGS.HAS_LD in instruction_form['flags']:
|
||||||
|
flags.append(INSTR_FLAGS.LD)
|
||||||
|
return latency_wo_load
|
||||||
|
|
||||||
def convert_mem_to_reg(self, memory, reg_type, reg_id='0'):
|
def substitute_mem_address(self, operands):
|
||||||
|
# reg_ops = [op for op in operands if 'register' in op]
|
||||||
|
# reg_type = self._parser.get_reg_type(reg_ops[0]['register'])
|
||||||
|
return [self._create_reg_wildcard() if 'memory' in op else op for op in operands]
|
||||||
|
|
||||||
|
def _create_reg_wildcard(self):
|
||||||
|
return {'*': '*'}
|
||||||
|
|
||||||
|
def convert_op_to_reg(self, reg_type, reg_id='0'):
|
||||||
if self._isa == 'x86':
|
if self._isa == 'x86':
|
||||||
if reg_type == 'gpr':
|
if reg_type == 'gpr':
|
||||||
register = {'register': {'name': 'r' + str(int(reg_id) + 9)}}
|
register = {'register': {'name': 'r' + str(int(reg_id) + 9)}}
|
||||||
|
|||||||
@@ -347,11 +347,21 @@ class MachineModel(object):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _check_operands(self, i_operands, operands):
|
def _check_operands(self, i_operand, operand):
|
||||||
|
# check for wildcard
|
||||||
|
if '*' in operand:
|
||||||
|
if (
|
||||||
|
'class' in i_operand
|
||||||
|
and i_operand['class'] == 'register'
|
||||||
|
or 'register' in i_operand
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
if self._data['isa'].lower() == 'aarch64':
|
if self._data['isa'].lower() == 'aarch64':
|
||||||
return self._check_AArch64_operands(i_operands, operands)
|
return self._check_AArch64_operands(i_operand, operand)
|
||||||
if self._data['isa'].lower() == 'x86':
|
if self._data['isa'].lower() == 'x86':
|
||||||
return self._check_x86_operands(i_operands, operands)
|
return self._check_x86_operands(i_operand, operand)
|
||||||
|
|
||||||
def _check_AArch64_operands(self, i_operand, operand):
|
def _check_AArch64_operands(self, i_operand, operand):
|
||||||
if 'class' in operand:
|
if 'class' in operand:
|
||||||
|
|||||||
Reference in New Issue
Block a user