1

I'm trying to make a function InvertCopy() that acts like memcpy(), except that it also invert each bit while doing the copy. First I made this:

void InvertCopy( void *v_dst, const void *v_src, int length )
{
    char *dst = v_dst;
    const char *src = v_src;

    for ( ; length>0; length-- )
    {
        *(dst++) = ~ *(src++);
    }
}

It works, but for performance concerns I wanted to take advantage of the word-size of the processor. For that an integer-pointer would be excellent, except my InvertCopy should handle both int pointers and non-int pointers, therefore I cannot simply convert the pointer to int* - on some processors it may actually cause hardware faults.

To make it easier I decided to allow slower performance when handling unaligned buffers, and only make this optimization when possible. The result was this:

#define IS_ALIGNED( addr, size )  ( ((uintptr_t)(addr)) % (size) == 0 )

void InvertCopy( void *v_dst, const void *v_src, int length )
{
    char *dst = v_dst;
    const char *src = v_src;

    /* Optimization starts here! */
    if ( IS_ALIGNED( dst, sizeof(int) ) && IS_ALIGNED( src, sizeof(int) ) )
    {
        int *i_dst = v_dst;
        const int *i_src = v_src;

        for ( ; length >= sizeof(int); length -= sizeof(int) )
        {
            *(i_dst++) = ~ *(i_src++);
        }

        dst = (char*) i_dst;
        src = (const char*) i_src;
    }
    /* Optimization done. */

    for ( ; length>0; length-- )
    {
        *(dst++) = ~ *(src++);
    }
}

This is great and actually works quite faster in my experiments.

But is this correct? GCC doesn't give me any warning when compiling with -Wcast-align, but I think that doesn't mean much since it also says nothing when I do the same without first checking the alignment.

So am I doing right or should I worry for alignment issues?

shapaz
  • 43
  • 4
  • It looks ok to me. But a better approach would be to copy the first few bytes until both buffers are aligned. This way you would use the optimization more often. See this related question: http://stackoverflow.com/questions/1898153/how-to-determine-if-memory-is-aligned-testing-for-alignment-not-aligning – Filipe Gonçalves May 03 '14 at 19:15

1 Answers1

0

Looks good to me. Just write up some unit tests using source and dest buffers of various alignments.

An additional improvement would be to also try to do a single-byte copy first, to bring the buffers up to the required alignment. Of course, this only works if both buffers start at the same alignment offset.

There are also some good articles out there about optimizing memcpy (which of course applies to your task as well).

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • Thanks for the improvement, but as you mentioned thats only for when the buffers have the same alignment offset, not for the general case. About the unit tests - I did check the code, but I'm worrying for what would happen if I try to run the code on some bizarre microcontroller. From the examples on your fisrt link I see they did exactly the same, so I guess it's fine. – shapaz May 04 '14 at 19:20