memcmp but need to compare block with fixed value

Arash Fotouhi picture Arash Fotouhi · Jun 11, 2013 · Viewed 7.4k times · Source

I need to compare a block of memory to a fixed value in C. Can I do this with memcmp? Something like:

memcmp (starting_address , fixed_value , num_byte)

I need fixed_value to be a fixed value not the starting address of a block.

  1. Writing the fixed value to an entire temporary memory block is not an option because I have limited space.
  2. Using a loop to write and check memory one by one is not an option because it's very slow.

If it's not possible can anyone tell me a solution that is as fast (or faster) than memcmp?

Thanks,

EDIT: Let's say I have 5GB of memory that holds 0's. And I'm trying to make sure they're all 0's. Is it safe to check the first byte of the block then do this:

memcmp (starting_address , starting_address + ONE_BYTE , FIVE_GB); ?

EDIT: This is why I need to use memcmp and not a user defined loop:

This code took 546 clock ticks to run:

memset(0x80000000 , 0x1 , 0x10000000);
memset(0x90000000 , 0x1 , 0x10000000);
memcmp(0x80000000 , 0x90000000 , 0x10000000);

vs this one that took 7669 clock ticks:

unsigned int i;
int flag = 0;
int *p = 0x80000000;
int *q = 0x90000000;
while(p < 0x90000000)
{
    if(*p++ != *q++)
    {
        flag = 1;
    }
}

Answer

nneonneo picture nneonneo · Jun 11, 2013

One solution:

Create a buffer containing all the same value and compare against it iteratively. That way you get the advantage of an efficient memcmp implementation without having to write too much code:

static char val[4096]; // tune the size of the buffer if desired
/* at initialization: memset(val, 0x01, sizeof(val)) */

char *start, *ptr, *end;
// initialize start and end
for(ptr = start; ptr < end-sizeof(val); ptr += sizeof(val)) {
    if(memcmp(ptr, val, sizeof(val))
        goto not_all_val;
}
if(memcmp(ptr, val, end - ptr))
    goto not_all_val;

/* all val */
puts("all val");
return;

not_all_val:
puts("not all val");
return;

Performance comparison:

10000 iterations of memcmp(buf, buf2, 4000000) (two buffers of the same length, same as the first method in the question):

real    0m7.480s
user    0m7.375s
sys 0m0.103s

10000 iterations of character-by-character comparison over 4000000 bytes (same as the second method):

real    0m27.004s
user    0m26.908s
sys 0m0.094s

10000 iterations of the proposed method above over 4000000 bytes:

real    0m3.194s
user    0m3.151s
sys 0m0.042s

YMMV (I'm on a three-year-old Macbook Pro), but this method is twice as fast as comparing a complete buffer (likely due to superior cache performance), and nearly ten times as fast as character-by-character comparison.