********** * Using the predicate model, surround the logical test with brackets as the first item on the line: ***** [llTest] .??. someCodeGoesHere() && Only executed if llTest is trueSomebody on another forum posted the message:
EXIT IF/WHEN lCondition LOOP IF/WHEN lConditionThat is the purpose of the predicate. For example:
[lCondition] .??. EXIT [lCondition] .??. LOOPThese can be read as:
IF lCondition k = doSomething(i) ENDIFThat would compile down into assembly as:
01: CMP lCondition,1 && "Compare lCondition to 1" 02: JNZ after && "If they are not equal, skip the next instruction" 03: MOV EDX,variable_i && Part 1 of 2 of the "(i)" part of the "k = doSomething(i)" command 04: PUSH EDX && Part 2 of 2 of the"(i)" part of the "k = doSomething(i)" command 05: CALL doSomething && The "doSomething()" part of the "k = doSomething(i)" command 06: MOV variable_k,EAX && Store the result "k =" part of the expression 07:after: 08: * Control would continue hereOn line 02, the CPU would use "branch prediction" algorithms to determine if it is more likely the branch would be taken or not taken. If it "guesses" wrong, then the entire instruction pipeline must be invalidated, emptied, and re-loaded with the proper destination set of instructions, either beginning at line 03, or line 08.
01: CMP lCondition,1 && "Compare lCondition to 1" 02:[Z] MOV EDX,variable_i && If ZERO? (meaning if they were equal), Part 1 of 2 of the "(i)" part of the "k = doSomething(i)" command 03:[Z] PUSH EDX && If ZERO? (meaning if they were equal), Part 2 of 2 of the"(i)" part of the "k = doSomething(i)" command 04:[Z] CALL doSomething && If ZERO? (meaning if they were equal), The "doSomething()" part of the "k = doSomething(i)" command 05:[Z] MOV variable_k,EAX && If ZERO? (meaning if they were equal), Store the result "k =" part of the expression 06:after: 07: * Control would continue hereWhereas in this case it ALWAYS executes the instructions 02,03,04,05, the result is that if the ZERO? flag is not set, it doesn't actually do anything so it's very fast. It is faster than skipping around those instructions because the instruction pipeline can be fully maintained without the requirement of refilling it, as this refilling operation is expensive in terms of clock cycles lost to fetch the new memory location, and begin decoding all of the parts of the instruction (as modern CPU pipelines are typically 10 or more steps to execute each machine opcode instruction).