7
\$\begingroup\$

I need to fast fill a memory block in C#, so I wrote something like this (in Free Pascal Compiler + Lazarus in 64 bit mode):

//  ECX = Ptr64
//  EDX = Count
//  R8  = Value

PROCEDURE Fill64 (VAR Ptr64; Count: QWord; Value: QWord);
BEGIN
  ASM
    PUSH    RDI
    MOV     RDI, RCX    // Destination Index = Ptr64
    MOV     RAX, R8     // Accumulator = Value
    MOV     RCX, RDX    // Counter Register = Count
    TEST    RCX, RCX    // If RCX is 0, set ZF (zero flag)
    JZ      @Exit       // Exit if ZF is set
    REP     STOSQ       // Fill memory using 64 bit value from RAX register
  @Exit:
    POP     RDI
  END;
END;    

And I use it from C#:

[DllImport ("MemUtil64.dll", EntryPoint = "Fill64", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe void Fill64 (void* ptr, ulong count, ulong value);

If this code okay, and fastest possible?

\$\endgroup\$
  • 2
    \$\begingroup\$ have you tested it against other possible implementations for speed? \$\endgroup\$ – Jean-Bernard Pellerin Apr 23 '13 at 22:09
  • 4
    \$\begingroup\$ The code is okay if unsafe is okay for you. You should understand that there is a possible vulnerability. Regarding performance, I see your question on SO (stackoverflow.com/questions/16178211/…), it has a good link in comments. Probably SSE would be faster. \$\endgroup\$ – Pavel Tupitsyn Apr 24 '13 at 9:32
  • \$\begingroup\$ @Jean-Bernard: Speed is OK, and its around 3GB/s when AIDA64 tells I have 5,5GB/s memory. It can be faster, but need SSE and advanced cache/tlb optimizations which I cannot understand. Comparing to pure C#, its 50% faster. \$\endgroup\$ – apocalypse Apr 25 '13 at 0:15
  • \$\begingroup\$ @Kefir: Yes, I will delete this stack overflow duplicate. \$\endgroup\$ – apocalypse Apr 25 '13 at 0:18
7
\$\begingroup\$

Unfortunately the answer is CPU-dependent. For example here is Android's memset implementation: it uses rep stosq for some CPUs and a different more complicated implementation (avoiding rep stosq) for others.

For further details, on Intel CPUs, refer to the "Enhanced REP MOVSB and STOSB operation (ERMSB)" section of the Intel® 64 and IA-32 Architectures Optimization Reference Manual.

\$\endgroup\$
  • \$\begingroup\$ Thanks. Rep Stosq is enough fast for me. Gives me 60% of mem bandwidth on my cpu. That optimization guide anyway is very useful. \$\endgroup\$ – apocalypse Mar 3 '14 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.