Recent

Author Topic: gdeque unit: const params  (Read 2101 times)

AlexTP

  • Hero Member
  • *****
  • Posts: 2402
    • UVviewsoft
gdeque unit: const params
« on: September 08, 2020, 11:53:42 pm »
https://github.com/graemeg/freepascal/blob/master/packages/fcl-stl/src/gdeque.pp

    procedure SetValue(position:SizeUInt; value:T);inline;
    procedure PushBack(value:T);inline;
    procedure PushFront(value:T);inline;
    procedure Insert(Position:SizeUInt; Value:T);inline;

My deque elements will be few Kb in size.
Isn't it better to use "const value: T" or even "constref value: T"?
« Last Edit: September 09, 2020, 10:37:33 am by Alextp »

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: gdeque unit: const params
« Reply #1 on: September 09, 2020, 03:51:36 am »
looks like more vector code...

Its like your first hello world program..

Everyone has to write a vector tree just to see if the compiler can do it, code too.

at least that's what it looks like...

My first vector was C++
The only true wisdom is knowing you know nothing

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: gdeque unit: const params
« Reply #2 on: September 09, 2020, 03:58:08 am »
Isn't it better to use "const value: T" or even "constref value: T"?

Yeah. I'd recommend the Dequeue from LGenerics instead honestly: https://github.com/avk959/LGenerics/blob/master/lgenerics/LGDeque.pas

AlexTP

  • Hero Member
  • *****
  • Posts: 2402
    • UVviewsoft
Re: gdeque unit: const params
« Reply #3 on: September 09, 2020, 09:23:07 am »
From LGenerics? It will get few more dependencies and code bloat. So I use gdeque.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: gdeque unit: const params
« Reply #4 on: September 09, 2020, 09:35:27 am »
Isn't it better to use "const value: T" or even "constref value: T"?

It's recommended to use const instead of constref as then the compiler can pick the optimal passing for the type (e.g. constref would pass an UInt32 as reference even if the calling convention would allow to pass it in a register).

AlexTP

  • Hero Member
  • *****
  • Posts: 2402
    • UVviewsoft
Re: gdeque unit: const params
« Reply #5 on: September 09, 2020, 10:37:52 am »
So let's change it to "const" in FPC?

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: gdeque unit: const params
« Reply #6 on: September 09, 2020, 12:23:58 pm »
Yes, but leave it to the author: forum member.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: gdeque unit: const params
« Reply #7 on: September 09, 2020, 05:47:27 pm »
It will get few more dependencies and code bloat.
Regarding the code bloat. This module clearly shows the excessive use of the "inline" directive. It is often placed wherever the code "looks" small, but it is not.
Let's take a simple example:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses gdeque;
  5.  
  6. type
  7.   TDequeString = specialize TDeque<AnsiString>;
  8. var
  9.   A: TDequeString;
  10. begin
  11.   A := TDequeString.Create;
  12.   try
  13.     A.PushBack('Test');
  14.     Writeln(A.Back);
  15.   finally
  16.     A.Free;
  17.   end;
  18. end.
Let's examine the generated code (FPC 3.2.0, x64, Intel, optimization level 3) for the Create:
Code: ASM  [Select][+][-]
  1. # [13] A := TDequeString.Create;
  2.         movl    $1,%eax
  3.         leaq    VMT_$P$PROJECT1_$$_TDEQUE$1$CRC6824777A(%rip),%rcx
  4.         movq    %rax,%rdx
  5.         call    P$PROJECT1$_$TDEQUE$1$CRC6824777A_$__$$_CREATE$$TDEQUE$1$CRC6824777A
  6.         movq    %rax,U_$P$PROJECT1_$$_A(%rip)
  7.  
Small and adequate - because it's not "inline".
Now let's look at the PushBack:
Code: ASM  [Select][+][-]
  1. # [15] A.PushBack('Test');
  2.         leaq    -8(%rbp),%rcx
  3.         call    fpc_ansistr_decr_ref
  4.         leaq    .Ld2(%rip),%rdx
  5.         leaq    -8(%rbp),%rcx
  6.         call    fpc_ansistr_assign
  7. .Ll182:
  8.         movq    U_$P$PROJECT1_$$_A(%rip),%rdx
  9. .Ll183:
  10.         movq    16(%rdx),%rax
  11.         cmpq    24(%rdx),%rax
  12. .Ll184:
  13.         jne     .Lj254
  14. .Ll185:
  15.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  16.         movq    24(%rax),%rbx
  17.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  18.         movq    24(%rax),%rax
  19.         shlq    $3,%rax
  20.         movq    U_$P$PROJECT1_$$_A(%rip),%rdx
  21.         cmpq    $0,24(%rdx)
  22.         jne     .Lj257
  23.         movq    U_$P$PROJECT1_$$_A(%rip),%rdx
  24.         movq    $4,24(%rdx)
  25.         jmp     .Lj258
  26. .Lj257:
  27.         cmpq    $1048576,%rax
  28.         jnb     .Lj260
  29. .Ll186:
  30.         movq    U_$P$PROJECT1_$$_A(%rip),%rcx
  31. .Ll187:
  32.         shlq    $1,24(%rcx)
  33.         jmp     .Lj261
  34. .Lj260:
  35.         cmpq    $268435456,%rax
  36.         jnb     .Lj263
  37. .Ll188:
  38.         movq    U_$P$PROJECT1_$$_A(%rip),%rcx
  39.         movq    24(%rcx),%rdx
  40. .Ll189:
  41.         movq    %rdx,%rax
  42.         shrq    $3,%rax
  43.         addq    %rdx,%rax
  44.         movq    %rax,24(%rcx)
  45.         jmp     .Lj264
  46. .Lj263:
  47. .Ll190:
  48.         movq    U_$P$PROJECT1_$$_A(%rip),%rcx
  49.         movq    24(%rcx),%rdx
  50. .Ll191:
  51.         movq    %rdx,%rax
  52.         shrq    $4,%rax
  53.         addq    %rdx,%rax
  54.         movq    %rax,24(%rcx)
  55. .Lj264:
  56. .Lj261:
  57. .Lj258:
  58.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  59.         movq    24(%rax),%rax
  60.         movq    %rax,-16(%rbp)
  61.         leaq    RTTI_$P$PROJECT1_$$_def00000002(%rip),%rdx
  62.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  63.         leaq    8(%rax),%rcx
  64.         leaq    -16(%rbp),%r9
  65.         movl    $1,%r8d
  66.         call    fpc_dynarray_setlength
  67.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  68.         cmpq    $0,32(%rax)
  69.         jna     .Lj266
  70.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  71.         movq    32(%rax),%rax
  72.         leaq    -1(%rax),%rsi
  73.         movq    $-1,%rdi
  74.         .balign 8,0x90
  75. .Lj267:
  76.         addq    $1,%rdi
  77.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  78.         movq    8(%rax),%rax
  79.         movq    (%rax,%rdi,8),%rdx
  80.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  81.         movq    8(%rax),%rcx
  82.         leaq    (%rbx,%rdi),%rax
  83.         leaq    (%rcx,%rax,8),%rcx
  84.         call    fpc_ansistr_assign
  85.         cmpq    %rdi,%rsi
  86.         jnbe    .Lj267
  87.         .balign 4,0x90
  88. .Lj266:
  89.         .balign 4,0x90
  90. .Lj254:
  91. .Ll192:
  92.         movq    U_$P$PROJECT1_$$_A(%rip),%rcx
  93. .Ll193:
  94.         movq    8(%rcx),%r8
  95.         movq    32(%rcx),%rdx
  96.         movq    16(%rcx),%rax
  97.         addq    %rdx,%rax
  98.         xorl    %edx,%edx
  99.         divq    24(%rcx)
  100.         leaq    (%r8,%rdx,8),%rcx
  101.         movq    -8(%rbp),%rdx
  102.         call    fpc_ansistr_assign
  103.         movq    U_$P$PROJECT1_$$_A(%rip),%rax
  104.         addq    $1,16(%rax)
And so it will be for every PushBack. Let me remind: the 3rd level of optimization!
Library authors should take a closer look at when to use the inline directive.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: gdeque unit: const params
« Reply #8 on: September 10, 2020, 09:28:27 am »
Yes, but leave it to the author: forum member.

It's now mainly maintained by the FPC devs. So if someone provides a patch and reports it it's likely going to be applied.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: gdeque unit: const params
« Reply #9 on: September 10, 2020, 11:25:05 am »
Aserge: how does the same look with a pure value type?

This case would need some auto-inline decision making then. (or ignoring the hint in the managed type case because it gets too complex)

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: gdeque unit: const params
« Reply #10 on: September 10, 2020, 08:25:44 pm »
Aserge: how does the same look with a pure value type?
Almost the same.
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses gdeque;
  5.  
  6. type
  7.   TDequeInteger = specialize TDeque<Integer>;
  8. var
  9.   A: TDequeInteger;
  10. begin
  11.   A := TDequeInteger.Create;
  12.   try
  13.     A.PushBack(100);
  14.     Writeln(A.Back);
  15.   finally
  16.     A.Free;
  17.   end;
  18. end.
Code: ASM  [Select][+][-]
  1. # [11] A := TDequeInteger.Create;
  2.         movl    $1,%eax
  3.         leaq    VMT_$P$PROGRAM_$$_TDEQUE$1$CRC9F312717(%rip),%rcx
  4.         movq    %rax,%rdx
  5.         call    P$PROGRAM$_$TDEQUE$1$CRC9F312717_$__$$_CREATE$$TDEQUE$1$CRC9F312717
  6.         movq    %rax,U_$P$PROGRAM_$$_A(%rip)
Code: ASM  [Select][+][-]
  1. # [13] A.PushBack(100);
  2.         movq    16(%rdx),%rax
  3.         cmpq    24(%rdx),%rax
  4. .Ll149:
  5.         jne     .Lj207
  6. .Ll150:
  7.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  8.         movq    24(%rax),%rbx
  9.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  10.         movq    24(%rax),%rax
  11.         shlq    $2,%rax
  12.         movq    U_$P$PROGRAM_$$_A(%rip),%rdx
  13.         cmpq    $0,24(%rdx)
  14.         jne     .Lj210
  15.         movq    U_$P$PROGRAM_$$_A(%rip),%rdx
  16.         movq    $4,24(%rdx)
  17.         jmp     .Lj211
  18. .Lj210:
  19.         cmpq    $1048576,%rax
  20.         jnb     .Lj213
  21. .Ll151:
  22.         movq    U_$P$PROGRAM_$$_A(%rip),%rcx
  23. .Ll152:
  24.         shlq    $1,24(%rcx)
  25.         jmp     .Lj214
  26. .Lj213:
  27.         cmpq    $268435456,%rax
  28.         jnb     .Lj216
  29. .Ll153:
  30.         movq    U_$P$PROGRAM_$$_A(%rip),%rcx
  31.         movq    24(%rcx),%rdx
  32. .Ll154:
  33.         movq    %rdx,%rax
  34.         shrq    $3,%rax
  35.         addq    %rdx,%rax
  36.         movq    %rax,24(%rcx)
  37.         jmp     .Lj217
  38. .Lj216:
  39. .Ll155:
  40.         movq    U_$P$PROGRAM_$$_A(%rip),%rcx
  41.         movq    24(%rcx),%rdx
  42. .Ll156:
  43.         movq    %rdx,%rax
  44.         shrq    $4,%rax
  45.         addq    %rdx,%rax
  46.         movq    %rax,24(%rcx)
  47. .Lj217:
  48. .Lj214:
  49. .Lj211:
  50.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  51.         movq    24(%rax),%rax
  52.         movq    %rax,-8(%rbp)
  53.         leaq    RTTI_$P$PROGRAM_$$_def00000002(%rip),%rdx
  54.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  55.         leaq    8(%rax),%rcx
  56.         leaq    -8(%rbp),%r9
  57.         movl    $1,%r8d
  58.         call    fpc_dynarray_setlength
  59.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  60.         cmpq    $0,32(%rax)
  61.         jna     .Lj219
  62.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  63.         movq    32(%rax),%rax
  64.         subq    $1,%rax
  65.         movq    $-1,%rdx
  66.         .balign 8,0x90
  67. .Lj220:
  68.         addq    $1,%rdx
  69. .Ll157:
  70.         movq    U_$P$PROGRAM_$$_A(%rip),%rcx
  71. .Ll158:
  72.         movq    8(%rcx),%r9
  73.         leaq    (%rbx,%rdx),%r8
  74.         movq    8(%rcx),%rcx
  75.         movl    (%rcx,%rdx,4),%ecx
  76.         movl    %ecx,(%r9,%r8,4)
  77.         cmpq    %rdx,%rax
  78.         jnbe    .Lj220
  79.         .balign 4,0x90
  80. .Lj219:
  81.         .balign 4,0x90
  82. .Lj207:
  83. .Ll159:
  84.         movq    U_$P$PROGRAM_$$_A(%rip),%rcx
  85. .Ll160:
  86.         movq    8(%rcx),%r8
  87.         movq    32(%rcx),%rdx
  88.         movq    16(%rcx),%rax
  89.         addq    %rdx,%rax
  90.         xorl    %edx,%edx
  91.         divq    24(%rcx)
  92.         movl    $100,(%r8,%rdx,4)
  93.         movq    U_$P$PROGRAM_$$_A(%rip),%rax
  94.         addq    $1,16(%rax)
  95. .Ll161:

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: gdeque unit: const params
« Reply #11 on: September 11, 2020, 04:01:04 pm »
It will get few more dependencies and code bloat.
Regarding the code bloat. This module clearly shows the excessive use of the "inline" directive. It is often placed wherever the code "looks"

I mean, what they were saying is that they think the TGDeque from LGenerics (a third party library) would bloat their code moreso than using FPC's TDeque.

Also, as far the inline, the problem there is the fact that PushBack calls IncreaseCapacity, and IncreaseCapacity is marked as inline when it really shouldn't be. It's definitely fine for PushBack itself to be inline, though.

 

TinyPortal © 2005-2018