Recent

Author Topic: assembler; + inline; How do I make friends? :-)  (Read 2909 times)

beria

  • Jr. Member
  • **
  • Posts: 70
assembler; + inline; How do I make friends? :-)
« on: September 29, 2022, 01:09:10 pm »
For example, I have one:
Code: Pascal  [Select][+][-]
  1.  procedure StrSwap(var S1, S2: WideString); assembler; stdcall; nostackframe; inline;
  2.   asm
  3.            MOV     RAX,qword ptr [S1]
  4.            MOV     R8,qword ptr [S2]
  5.            MOV     qword ptr [S1],R8
  6.            MOV     qword ptr [S2],RAX
  7.   end;      

It is analogous, only 250 times faster than:

Code: Pascal  [Select][+][-]
  1.   procedure StrSwap(var S1, S2: WideString); inline;
  2.   var
  3.     S3: WideString;
  4.   begin
  5.     S3 := S2;
  6.     S2 := S1;
  7.     S1 := S3;
  8.   end;  


but how to make it always "inline"... The compiler writes that "assembler" and "inline" are incompatible, but I don't understand why, if in FPC source codes such mappings are used all the time?

avk

  • Hero Member
  • *****
  • Posts: 752
Re: assembler; + inline; How do I make friends? :-)
« Reply #1 on: September 29, 2022, 02:05:15 pm »
What about this version without any assembler?
Code: Pascal  [Select][+][-]
  1. procedure StrSwap(var S1, S2: widestring); inline;
  2. var
  3.   S3: Pointer;
  4. begin
  5.   S3 := Pointer(S2);
  6.   Pointer(S2) := Pointer(S1);
  7.   Pointer(S1) := S3;
  8. end;
  9.  

beria

  • Jr. Member
  • **
  • Posts: 70
Re: assembler; + inline; How do I make friends? :-)
« Reply #2 on: September 29, 2022, 02:12:02 pm »
What about this version without any assembler?

It's not about the specific procedure, it's only as an example, although I have quite working, but how to do it in general.... For on the one hand it is possible and there are examples, but on the other hand the compiler does not allow...

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: assembler; + inline; How do I make friends? :-)
« Reply #3 on: September 29, 2022, 02:15:03 pm »
but how to make it always "inline"... The compiler writes that "assembler" and "inline" are incompatible, but I don't understand why, if in FPC source codes such mappings are used all the time?

Assembler routines can not be inlined, because the compiler has no real knowledge about what you're doing in that assembly code and what side effects some instruction might have. This would cause problems when the compiler assumes a certain state. A function call boundary protects here in most cases and thus assembly code either needs to be in a asmend-block (preferably with a list of modified registers) or it needs to be in a separate function which simply will not be inlined.

440bx

  • Hero Member
  • *****
  • Posts: 3921
Re: assembler; + inline; How do I make friends? :-)
« Reply #4 on: September 29, 2022, 02:25:40 pm »
Assembler routines can not be inlined, because the compiler has no real knowledge about what you're doing in that assembly code and what side effects some instruction might have. This would cause problems when the compiler assumes a certain state. A function call boundary protects here in most cases and thus assembly code either needs to be in a asmend-block (preferably with a list of modified registers) or it needs to be in a separate function which simply will not be inlined.
Understandable and very reasonable.  However, it would be nice if there was a way to tell the compiler "inline it anyway, I take full responsibility".

I commonly use code like this:
Code: Pascal  [Select][+][-]
  1. if <somecondition> then
  2. begin
  3.    { <somecondition> cannot happen unless there is a bug in this program }
  4.  
  5.   if IsDebuggerPresent() then asm int 3 end;
  6.  
  7.   exit;
  8. end;
  9.  
That "int 3" statement won't break any assumptions the compiler might make about the rest of the Pascal code but, because of that single "asm int 3" it won't inline it and, in that particular case the inline assembler is totally innocuous.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14161
  • Probably until I exterminate Putin.
Re: assembler; + inline; How do I make friends? :-)
« Reply #5 on: September 29, 2022, 03:32:29 pm »
int 3 is an instruction that should always break. What's the fuss about? It is by design.
Since https://www.cpu-world.com/CPUs/8080/  or the Intel docs.


That's almost before I was born and i am 64...... ;D
« Last Edit: September 29, 2022, 03:39:44 pm by Thaddy »
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3921
Re: assembler; + inline; How do I make friends? :-)
« Reply #6 on: September 29, 2022, 03:50:31 pm »
int 3 is an instruction that should always break. What's the fuss about? It is by design.
Since https://www.cpu-world.com/CPUs/8080/  or the Intel docs.


That's almost before I was born and i am 64...... ;D
Apparently, in 64 years you haven't learned that one thing int 3 won't break are any assumptions a compiler may make about register usage. Therefore, it would be safe for the compiler to inline any function/procedure which only uses int 3.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

abouchez

  • Full Member
  • ***
  • Posts: 110
    • Synopse
Re: assembler; + inline; How do I make friends? :-)
« Reply #7 on: September 29, 2022, 05:24:28 pm »
Today, I don't use asm but for very specific tasks using specific opcodes, like SSE2, AES-NI, AVX or SSE4.2.
... and you will find thousands of lines of such manually tuned asm in mORMot, e.g. just for x86_64 https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.base.asmx64.inc and https://github.com/synopse/mORMot2/blob/master/src/crypt/mormot.crypt.core.asmx64.inc or even https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.fpcx64mm.pas

Otherwise, especially if I want the FPC compiler to inline, I write pascal code.
With some tricks like pointer arithmetic for some core routines.

And latest versions of FPC tends to generate very good code.
The pointer() trick is to be used for this example. It will be properly inlined, it will be really cross-platform and cross-CPU, and it will be faster than manual non-inline asm.

To be fair, inlining asm would need more than... inlining... to be efficient.
You will need proper register allocation by the compiler, therefore you would need something closer to C/C++ intrinsics.
In real projects, inlining asm is used in a very few places. Intrinsics are the way to go. Or write the asm in high-level languages like Perl or other DSL.

So don't make premature optimization.
Root of all evil. ;)
And trust the RTL and some tuned libraries to be fast enough for most of the purposes.
« Last Edit: September 29, 2022, 05:34:11 pm by abouchez »

Thaddy

  • Hero Member
  • *****
  • Posts: 14161
  • Probably until I exterminate Putin.
Re: assembler; + inline; How do I make friends? :-)
« Reply #8 on: September 29, 2022, 06:07:45 pm »
int 3 is an instruction that should always break. What's the fuss about? It is by design.
Since https://www.cpu-world.com/CPUs/8080/  or the Intel docs.


That's almost before I was born and i am 64...... ;D
Apparently, in 64 years you haven't learned that one thing int 3 won't break are any assumptions a compiler may make about register usage. Therefore, it would be safe for the compiler to inline any function/procedure which only uses int 3.
Well, before you make any further comments, my pension is payed. Three months to go ... Good luck with lizzy.
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3921
Re: assembler; + inline; How do I make friends? :-)
« Reply #9 on: September 29, 2022, 06:19:01 pm »
my pension is payed.
your pension is payed ?... I see you haven't learned the meaning of "payed" yet, in spite of the fact that this is the second time you misuse it and that it is pointed out to you.  Good for you that your pension won't leak.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: assembler; + inline; How do I make friends? :-)
« Reply #10 on: September 29, 2022, 06:22:35 pm »
What about this version without any assembler?

It's not about the specific procedure, it's only as an example, although I have quite working, but how to do it in general.... For on the one hand it is possible and there are examples, but on the other hand the compiler does not allow...

I had hoped that my message was clear: if you can do without assembler, you should do without it. If a pure Pascal subroutine seemed to be many times slower than a similar assembler one, it might be worth taking a closer look at its code.
And your example demonstrates this very well.

Thaddy

  • Hero Member
  • *****
  • Posts: 14161
  • Probably until I exterminate Putin.
Re: assembler; + inline; How do I make friends? :-)
« Reply #11 on: September 29, 2022, 06:25:31 pm »
my pension is payed.
your pension is payed ?... I see you haven't learned the meaning of "payed" yet, in spite of the fact that this is the second time you misuse it and that it is pointed out to you.  Good for you that your pension won't leak.
20% programming of which is 5% Pascal, 75% management. The  left-over is sheer luck.

When in France...
« Last Edit: September 29, 2022, 06:27:12 pm by Thaddy »
Specialize a type, not a var.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: assembler; + inline; How do I make friends? :-)
« Reply #12 on: September 29, 2022, 10:04:51 pm »
For example, I have one:
Code: Pascal  [Select][+][-]
  1.  procedure StrSwap(var S1, S2: WideString); assembler; stdcall; nostackframe; inline;
  2.   asm
  3.            MOV     RAX,qword ptr [S1]
  4.            MOV     R8,qword ptr [S2]
  5.            MOV     qword ptr [S1],R8
  6.            MOV     qword ptr [S2],RAX
  7.   end;      

It is analogous, only 250 times faster than:

Code: Pascal  [Select][+][-]
  1.   procedure StrSwap(var S1, S2: WideString); inline;
  2.   var
  3.     S3: WideString;
  4.   begin
  5.     S3 := S2;
  6.     S2 := S1;
  7.     S1 := S3;
  8.   end;  


but how to make it always "inline"... The compiler writes that "assembler" and "inline" are incompatible, but I don't understand why, if in FPC source codes such mappings are used all the time?

It is analogous, only 250 times faster than:
I wonder how you measured that.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

beria

  • Jr. Member
  • **
  • Posts: 70
Re: assembler; + inline; How do I make friends? :-)
« Reply #13 on: September 29, 2022, 11:45:13 pm »
What about this version without any assembler?

It's not about the specific procedure, it's only as an example, although I have quite working, but how to do it in general.... For on the one hand it is possible and there are examples, but on the other hand the compiler does not allow...

I had hoped that my message was clear: if you can do without assembler, you should do without it. If a pure Pascal subroutine seemed to be many times slower than a similar assembler one, it might be worth taking a closer look at its code.
And your example demonstrates this very well.

This was an example. I can rewrite the same thing on MMX,SSE,AVX 1-2-512 and no pascal will do so close....

beria

  • Jr. Member
  • **
  • Posts: 70

 

TinyPortal © 2005-2018