How initialize a data memory area as quickly as possible?

General FreeBASIC programming questions.
dodicat
Posts: 6232
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How initialize a data memory area as quickly as possible

Postby dodicat » Sep 08, 2015 19:49

Yea, I know fxm.
I had just created a pseudo array.

For the real thing, UDT operations are pitifully slow.

Code: Select all

#define DIMSIZE 58
#define BitSys 32       '' or 64

type _byte
     as byte dummy =6
end type

type udt
    as _byte A(DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1)
end type

  redim shared as byte array(DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1)
    dim as byte ptr p = @array(0,0,0,0,0)
    dim as double t1,t2
    dim as longint size
    size = DIMSIZE^5
    dim  as integer i1, i2, i3, i4, i5, LimitOutput = 15
   
    #macro _init_asm
    print "using: asm ":    '[asg]
    t1 = timer
  #if (BitSys = 64)   /'  FOR THE 64 BIT SYS '/
    asm
        push    rdi
        mov     rdi, p
        mov     rax, 0x0505050505050505
        mov     rcx, DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE / 8
        rep     stosq
        pop     rdi   
    end asm
  #else               /'  FOR THE 32 BIT SYS '/
    asm
        push    edi
        mov     edi, [p]
        mov     eax, 0x05050505
        mov     ecx, DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE / 4
        rep     stosd
        pop     edi
    end asm
  #endif
    t2 = timer
    print size / 1e9 / (t2-t1); " GB/s"; using " (##.########## s)";t2-t1
    print
#endmacro


 #macro _init_udt()
   print "using: udt ":
   t1=timer
   dim shared as UDT Q
   t2=timer
   print size / 1e9 / (t2-t1); " GB/s "; using " (##.########## s)";t2-t1
   print
   #endmacro
   
   #macro display(array,dot,dot1)
for z as integer = 1 to LimitOutput
        i1 = int(rnd * DIMSIZE)
        i2 = int(rnd * DIMSIZE)
        i3 = int(rnd * DIMSIZE)
        i4 = int(rnd * DIMSIZE)
        i5 = int(rnd * DIMSIZE)
        print array dot(i1,i2,i3,i4,i5)dot1;" ";
    next z
    print
    #endmacro

'================================================================


   _Init_asm
  display(array,,)

   _init_udt()
     display(Q,.A,.dummy)
     print
     
   sleep
fxm
Posts: 9529
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How initialize a data memory area as quickly as possible

Postby fxm » Sep 08, 2015 20:21

Until now, this was a serious thread!
Stop the magic tricks!

Code: Select all

t1=timer
dim shared as UDT Q
t2=timer
Because of modifier Shared, this instruction line is really executed at the program beginning and not between the two Timer readings.

For example put rather in this place:

Code: Select all

   t1=timer
   'dim shared as UDT Q
   dim as UDT ptr pQ = New UDT
   #define Q (*pQ)
   t2=timer
dodicat
Posts: 6232
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How initialize a data memory area as quickly as possible

Postby dodicat » Sep 08, 2015 20:43

Well fxm, I did say that udt's were pityfuly slow at initialising.
So no magic trick!

And how am I making the thread less serious?
I have introduced the memcpy and udt methods so far here.

If it was the case that experimenting and posting were so critically analysed then perhaps I should post nothing at all in any thread.
I don't think so!
fxm
Posts: 9529
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How initialize a data memory area as quickly as possible

Postby fxm » Sep 08, 2015 21:07

I think mainly users who consider this kind of thread as an extension of the documentation.
We can not let them be deceived!
RockTheSchock
Posts: 226
Joined: Mar 12, 2006 16:25

Re: How initialize a data memory area as quickly as possible

Postby RockTheSchock » Sep 08, 2015 21:30

Remember the question! "How initialize a data memory area as quickly as possible?"

Well. i have asked for a bigger picture once because there are other solutions than only optimizing speed of data writes. A much more effective way could be to minimize the size of memory to clear. Or another way could be to clear memory block in a seperate thread while there are some other time consuming tasks like disk io or cpu/gpu computationally intensive calculations.

But without more information there is no chance for additional / better solutions.
dodicat
Posts: 6232
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How initialize a data memory area as quickly as possible

Postby dodicat » Sep 08, 2015 21:42

Yea, OK fxm.
Thank you Rock The Schock.

Here is my last post here.
Using udt (and keeping the array loading inside the timer as you suggest)
It about equals the asm method.

Code: Select all

#define DIMSIZE 58
#define BitSys 32       '' or 64

type _byte
     const as byte dummy =6
     as byte null
end type

type udt
    as _byte A(DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1)
end type

  redim shared as byte array(DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1,DIMSIZE-1)
    dim as byte ptr p = @array(0,0,0,0,0)
    dim as double t1,t2
    dim as longint size
    size = DIMSIZE^5
    dim  as integer i1, i2, i3, i4, i5, LimitOutput = 15
   
    #macro _init_asm
    print "using: asm ":    '[asg]
    t1 = timer
  #if (BitSys = 64)   /'  FOR THE 64 BIT SYS '/
    asm
        push    rdi
        mov     rdi, p
        mov     rax, 0x0505050505050505
        mov     rcx, DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE / 8
        rep     stosq
        pop     rdi   
    end asm
  #else               /'  FOR THE 32 BIT SYS '/
    asm
        push    edi
        mov     edi, [p]
        mov     eax, 0x05050505
        mov     ecx, DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE * DIMSIZE / 4
        rep     stosd
        pop     edi
    end asm
  #endif
    t2 = timer
    print size / 1e9 / (t2-t1); " GB/s"; using " (##.########## s)";t2-t1
    print
#endmacro


 #macro _init_udt()
   print "using: udt ":
   t1=timer
    pQ = New UDT
   t2=timer
   print size / 1e9 / (t2-t1); " GB/s "; using " (##.########## s)";t2-t1
   print
   #endmacro
   
   #macro display(array,dot,dot1)
for z as integer = 1 to LimitOutput
        i1 = int(rnd * DIMSIZE)
        i2 = int(rnd * DIMSIZE)
        i3 = int(rnd * DIMSIZE)
        i4 = int(rnd * DIMSIZE)
        i5 = int(rnd * DIMSIZE)
        print array dot(i1,i2,i3,i4,i5)dot1;" ";
    next z
    print
    #endmacro

'================================================================
dim shared as udt ptr pq
#define Q (*pQ)
do
   _Init_asm
  display(array,,)

   _init_udt()
     display(Q,.A,.dummy)
    print "________________________"
  sleep 1000
 delete pq
  loop until inkey=chr(27)
     
   
   sleep
   sleep
fxm
Posts: 9529
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How initialize a data memory area as quickly as possible

Postby fxm » Sep 08, 2015 22:10

Last joke!

Code: Select all

type _byte
     ''const as byte dummy =6
     ''as byte null
     as byte dummy =6
end type
otherwise, no initializing of array bytes!

With the correct member variable and initializer, use the UDTs is slower (compared to asm) by a factor of about 8 (50 when compiled with option '-exx'!), because for each array element, the constructor of _byte is called each time with one passed parameter (the implicit 'This').
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: How initialize a data memory area as quickly as possible

Postby MichaelW » Sep 09, 2015 20:13

MrSwiss wrote:@MichaelW,

regarding the article you've pointed to ... the code for calling the function reads:

Code: Select all

        mov     dword ptr [rsp+0x20], 5     ; output parameter 5
        mov     r9d, 4                      ; output parameter 4
        mov     r8d, 3                      ; output parameter 3
        mov     edx, 2                      ; output parameter 2
        mov     ecx, 1                      ; output parameter 1
        call    SomeFunction                ; Go Speed Racer!
However, there seems to be some faults:
    1) dword ptr [rsp+0x20] (shouldn't that be qword ptr ??)
    2) r9d (is this just the lower dword of r9??)
    3) the same goes for line r8d??
    4) edx (rdx??)
    5) ecx (rcx??)
this seems to be misleading information.

The function prototype specifies that the arguments are all dwords:

Code: Select all

void SomeFunction(int a, int b, int c, int d, int e);

So the code is accessing them as dwords. And in case it's not clear, the "dword ptr" specifies the instruction operand size, required for memory operands when the other operand is not a register that the assembler can use to infer the operand size.

Return to “General”

Who is online

Users browsing this forum: No registered users and 3 guests