Skip to content

McCode uses repeated if blocks to implement EXTEND #34

@g5t

Description

@g5t

At the end of a component TRACE function any instances which provided an EXTEND block introduce an if statement guarded block for its extend implementation.
The conditional statement checks the instance component number against the current component number, which is true exactly once for each particle.
If multiple components of the same type provide EXTEND blocks then an equal number of if statements are generated.
If those components happen to define the same EXTEND block, an equal number of copies of that block will be generated.

Example

For a test instrument that contains component instances generated by

        for i in range(100):
            instr += f"COMPONENT slit_{i} = Slit(xwidth=0.01, yheight=1)\n"
            instr += f"          AT ({sin(i/180 * pi)}, 0, {cos(i/180 * pi)}) RELATIVE sample\n"
            instr += f"          EXTEND %{{ who = (SCATTERED) ? {i}: 0; %}}\n"
            instr += f"COMPONENT detector_{i} = Arm() WHEN ({i} == who) AT (0, 0, 1) RELATIVE slit_{i}\n"
            instr += f"          EXTEND %{{ what = (SCATTERED) ? 1: 0; %}}\n"

The Slit trace function ends with

if (_comp->_index == 10) { // EXTEND slit_0
 who = (SCATTERED) ? 0: 0; 
}
if (_comp->_index == 12) { // EXTEND slit_1
 who = (SCATTERED) ? 1: 0; 
}
...
if (_comp->_index == 206) { // EXTEND slit_98
 who = (SCATTERED) ? 98: 0; 
}
if (_comp->_index == 208) { // EXTEND slit_99
 who = (SCATTERED) ? 99: 0; 
}

and the Arm trace function ends with

if (_comp->_index == 11) { // EXTEND detector_0
 what = (SCATTERED) ? 1: 0; 
}
if (_comp->_index == 13) { // EXTEND detector_1
 what = (SCATTERED) ? 1: 0; 
}
...
if (_comp->_index == 207) { // EXTEND detector_98
 what = (SCATTERED) ? 1: 0; 
}
if (_comp->_index == 209) { // EXTEND detector_99
 what = (SCATTERED) ? 1: 0; 
}

Ideas

  • Replacing the repeated extend block bodies by a function call is likely detrimental to the runtime.
  • Replacing the repeated if statements with a switch statement could allow the compiler to remove a large number of conditional checks
    • and could remove repeated blocks by utilizing case fall through.

Possible replacement

The Slit trace part:

switch (_comp->_index) {
case 9: // EXTEND slit_0
{ who = (SCATTERED) ? 0: 0; 
break;
}
case 11: // EXTEND slit_1
{ who = (SCATTERED) ? 1: 0; 
break;
}
case 13: // EXTEND slit_2
{ who = (SCATTERED) ? 2: 0; 
break;
}
...
case 205: // EXTEND slit_98
{ who = (SCATTERED) ? 98: 0; 
break;
}
case 207: // EXTEND slit_99
{ who = (SCATTERED) ? 99: 0; 
break;
}
default: break;
}

The Arm trace part:

switch (_comp->_index) {
case 10: // EXTEND detector_0
case 12: // EXTEND detector_1
...
case 206: // EXTEND detector_98
case 208: // EXTEND detector_99
{ what = (SCATTERED) ? 1: 0; 
break;
}
default: break;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions