Forum > General

Questions regarding the use of ORD to optimize the code

(1/6) > >>

lagprogramming:
Questions regarding the use of ORD in order to optimize the produced code in a particular situation

I'd like to optimize a line that looks like: if variable<value then variable:=1 else variable:=0;
I'm thinking of using ORD as it looks in the following code:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function Version1(z,x:sizeint):sizeint;begin  if z<x then result:=1 else result:=0;end; function Version2(z,x:sizeint):sizeint;begin  result:=ord(z<x);end;  .section .text.n_unit1_$$_version1$int64$int64$$int64        .balign 16,0x90        .type   UNIT1_$$_VERSION1$INT64$INT64$$INT64,@functionUNIT1_$$_VERSION1$INT64$INT64$$INT64:.Lc1:# Var $result located in register rax# Var z located in register rdi# Var x located in register rsi# [unit1.pas]# [33] begin.Ll1:# [34] if z<x then result:=1 else result:=0;        cmpq    %rdi,%rsi        jng     .Lj6        movl    $1,%eax        ret.Lj6:        xorl    %eax,%eax.Ll2:# [35] end;        ret.Lc2:.Lt1:.Le0:        .size   UNIT1_$$_VERSION1$INT64$INT64$$INT64, .Le0 - UNIT1_$$_VERSION1$INT64$INT64$$INT64.Ll3: .section .text.n_unit1_$$_version2$int64$int64$$int64        .balign 16,0x90        .type   UNIT1_$$_VERSION2$INT64$INT64$$INT64,@functionUNIT1_$$_VERSION2$INT64$INT64$$INT64:.Lc3:# Var $result located in register rax# Var z located in register rdi# Var x located in register rsi# [38] begin.Ll4:# [39] result:=ord(z<x);        cmpq    %rdi,%rsi        setgb   %al        andl    $255,%eax# Var $result located in register rax.Ll5:# [40] end;        ret.Lc4:.Lt2:.Le1:        .size   UNIT1_$$_VERSION2$INT64$INT64$$INT64, .Le1 - UNIT1_$$_VERSION2$INT64$INT64$$INT64.Ll6: 1)RTL reference guide "75.11.214 Ord" is not clear enough to me. Is it guaranteed that no matter the target platform ord(booleancondition) returns 1 or 0? If the answer is yes then no matter the target platform "if booleancondition then assign 1 else assign 0" can be replaced with "assign ord(booleancondition)".
2)The advantage of using ord is that it avoids a potential conditional branch miss. Should this kind of optimization be done at user level or it should be done automatically by the compiler depending on the optimization level and the target platform? Is there an architecture where using IF instead of ORD would be better?

Warfley:
Ord is used like this in the RTL:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function Sign(const AValue: Double): TValueSign;inline; begin  Result:=ord(AValue>0.0)-ord(AValue<0.0);end;So I think this is expected behavior.

I also think it is somewhere documented that True = 1 and False = 0 but I havent found that in a quick search. That said, not every boolean that is true is necessarily true

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  b: Boolean;begin  b := Boolean(4);  WriteLn(Ord(b));  if b = True then    WriteLn('b is True');  if ord(b) <> ord(True) then    WriteLn('b is not truely True'); Result:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---4b is Trueb is not truely TrueThis might occur in places where you simply cast integer return values to booleans, as it is often the case with (c based) system APIs. But for what you are doing this has no effect

MarkMLl:
I think you would be unwise assuming numeric values for Booleans unless *explicitly* documented. We all do it though :-)

The bottom line is that you should be inspecting the (assembler) code generated by the compiler at different optimisation levels before making further assumptions. However also see the link I posted at https://forum.lazarus.freepascal.org/index.php/topic,59197.msg441331.html#msg441331 yesterday.

MarkMLl

winni:
Hi!

In the unit math the function sign is defined for integer, int64 and all three float types:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function Sign(const AValue:  ....): TValueSign;
where TValueSign is defined:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TValueSign = -1..1;  

this has nothing to do with ord but with negativ, zero, positiv

Winni

Warfley:

--- Quote from: winni on April 29, 2022, 06:22:55 pm ---this has nothing to do with ord but with negativ, zero, positiv

--- End quote ---
Did you stop reading after the first line? It is followed up with/implemented as:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  Result:=ord(AValue>0.0)-ord(AValue<0.0);Or do you want to tell me that using ord to compute the result as an integer expression does not have anything to do with ord?


--- Quote from: jamie on April 29, 2022, 06:29:14 pm ---The value u really can depend on is false. That should always be 0

--- End quote ---
This is not necessarily true. The language can define what is the result of comparisons, as well as the value of the true constant.
So for example in C and C++, any number that is not 0 is considered "true" but it is well defined that pretty much all standard comparisons that return a boolean return the constant "true" if it is true, which is defined as 1.
So in C, it is well defined that (x > y) is either 0 or 1. Even though you could put any other value into a boolean (considering either C99 or C++, earlier versions of C did not have a boolean type to begin with)

The question is if that is also true for Pascal, the as boolean handling of which is quite similar to C otherwise

Navigation

[0] Message Index

[#] Next page

Go to full version