Page 1 of 1

Moving x number of bytes to another location

Posted: Sat Dec 21, 2013 9:56 pm
by netmaestro

Code: Select all

  CopyMemory(codestrings(current_code)\cs(), @*outstream\byte[0]+*outstream\index, codestrings(current_code)\index)
  *outstream\index + codestrings(current_code)\index
I have a program that runs more slowly than I would like. I've traced the time consumption to these two lines of code. Basically all that's happening here is that I'm moving the contents of an array of bytes (type .a actually) to an indexed location in a block of allocated memory. Can anyone help me with an asm routine that would move the bytes more quickly than CopyMemory is currently doing it?

Here's a working snippet:

Code: Select all

Structure decoder_table
  index.l
  Array cs.a(200)
EndStructure

Structure colorbits
  index.l
  byte.a[0]
EndStructure

Dim codestrings.decoder_table(0)
codestrings(0)\index = 150

*outstream.colorbits = AllocateMemory(1024)
*outstream\index = 100

; Move 150 bytes from codestrings array to outstream starting at *outstream\index
CopyMemory(codestrings(0)\cs(), @*outstream\byte[0]+*outstream\index, codestrings(0)\index)
Any hellep wilbert appreciated as idlelike to get this to go faster.

(sorry for my english I'm just learning)

Re: Moving x number of bytes to another location

Posted: Sun Dec 22, 2013 2:18 am
by netmaestro
Ok, I was able to come up with this:

Code: Select all

Procedure CopyPattern(*source, *dest, size)
  !cld
  !mov esi, [esp+4]
  !mov edi, [esp+8]
  !mov ecx, [esp+12]
  !rep movsb
EndProcedure
It works fine but it's exactly the same speed as CopyMemory :cry:

Is there a better way? Maybe with mmx? I don't know how to use that very well.

Re: Moving x number of bytes to another location

Posted: Sun Dec 22, 2013 2:41 am
by Crusiatus Black
When I test the rep movsb method, I get a slower result than with CopyMemory.

CopyMemory: 328ms
rep movsb method: 877ms

That's with PB 5.21 LTS x86 with debugger off.

memcpy results in slightly faster code in my tests; ranging from 244ms to 294ms

Code: Select all

Structure decoder_table
  index.l
  Array cs.a(200)
EndStructure

Structure colorbits
  index.l
  byte.a[0]
EndStructure

Dim codestrings.decoder_table(0)
codestrings(0)\index = 150

*outstream.colorbits = AllocateMemory(1024)
*outstream\index = 100

; Move 150 bytes from codestrings array to outstream starting at *outstream\index
#test_size = 9999999

s1 = ElapsedMilliseconds()
For i = 1 To #test_size
  CopyMemory(codestrings(0)\cs(), @*outstream\byte[0]+*outstream\index, codestrings(0)\index)
Next 
e1 = ElapsedMilliseconds()

Procedure CopyPattern(*source, *dest, size)
  !cld
  !mov esi, [esp+4]
  !mov edi, [esp+8]
  !mov ecx, [esp+12]
  !rep movsb
EndProcedure

ImportC "" : memcpy.i (*dest, *src, sz) : EndImport

s2 = ElapsedMilliseconds()
For i = 1 To #test_size
  ;CopyPattern(codestrings(0)\cs(), @*outstream\byte[0]+*outstream\index, codestrings(0)\index)
  memcpy(@*outstream\byte[0]+*outstream\index, codestrings(0)\cs(), codestrings(0)\index)
Next 
e2 = ElapsedMilliseconds()

OpenConsole()
PrintN("time1: " + Str(e1 - s1) + "ms")
PrintN("time2: " + Str(e2 - s2) + "ms")

ImportC ""
  system.i   (command.s)
EndImport

system("pause")

Re: Moving x number of bytes to another location

Posted: Sun Dec 22, 2013 6:54 am
by wilbert
CopyMemory isn't that slow I think.
What would be the fastest approach depends on the cpu.
According to Thorium this would be the fastest on a Core i7
http://www.purebasic.fr/english/viewtop ... 02#p359802

Re: Moving x number of bytes to another location

Posted: Mon Jan 06, 2014 11:41 am
by Thorium
wilbert wrote:CopyMemory isn't that slow I think.
What would be the fastest approach depends on the cpu.
According to Thorium this would be the fastest on a Core i7
http://www.purebasic.fr/english/viewtop ... 02#p359802
If a lot of small blocks are copied the push and pop need to be eliminated. They slow down the routine significantly if you are just copieing small blocks. Use a register instead.
Also the call itself may be the slow part, if you call it very often in a loop. So write the loop in Asm and inline the memory copy routine.