Skip to content

Instantly share code, notes, and snippets.

@mopp
Created September 27, 2014 16:30
Show Gist options
  • Save mopp/1ce461fc3e9d98b9dbf3 to your computer and use it in GitHub Desktop.
Save mopp/1ce461fc3e9d98b9dbf3 to your computer and use it in GitHub Desktop.
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
double gettimeofday_sec() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec * 1e-6;
}
static void* memset0(void* s, int c, size_t n) {
if (n != 0) {
register uintptr_t addr = (uintptr_t)s;
register uintptr_t t = addr + n;
if (((addr | n) & 1) == 0) {
for (unsigned int val = (uint8_t)c | (uint8_t)c << 8; addr < t; addr += sizeof(uint16_t)) {
*(uint16_t*)addr = val;
}
}
for (; addr < t; ++addr)
*(uint8_t*)addr = c;
}
return s;
}
static void* memset0_no(void* s, int c, size_t n) {
if (n != 0) {
uintptr_t addr = (uintptr_t)s;
uintptr_t t = addr + n;
if (((addr | n) & 1) == 0) {
for (unsigned int val = (uint8_t)c | (uint8_t)c << 8; addr < t; addr += sizeof(uint16_t)) {
*(uint16_t*)addr = val;
}
}
for (; addr < t; ++addr)
*(uint8_t*)addr = c;
}
return s;
}
static void* memset1(void* buf, int ch, size_t n) {
unsigned char* t = (unsigned char*)buf;
while (0 < n--) {
*t++ = (unsigned char const)ch;
}
return buf;
}
static void* memset2(void* s, int c, size_t n) {
if (s == NULL) {
return s;
}
register uintptr_t itr = (uintptr_t)s;
register uintptr_t end = itr + n;
uint8_t const uc = (uint8_t const)c;
if (((itr | n) & 0x3) == 0) {
register uint32_t v = ((uc << 24) | (uc << 16) | (uc << 8) | uc);
while (itr < end) {
*(uint32_t*)(itr++) = v;
itr += sizeof(uint32_t);
}
} else if (((itr | n) & 0x1) == 0) {
/* word */
register uint16_t v = ((uc << 8) | uc);
while (itr < end) {
*(uint16_t*)(itr++) = v;
itr += sizeof(uint16_t);
}
}
/* byte */
while (itr < end) {
*(uint8_t*)(itr++) = uc;
}
return s;
}
bool validate(register uint8_t* s, register uint8_t c, size_t n) {
register uint8_t* e = s + n;
while (s < e) {
if (*s++ != c) {
printf("%p\n", s);
return false;
}
}
return true;
}
void worker(void* (*f)(void*, int, size_t), void* s, int c, size_t n) {
static size_t const times = 10;
double t1, t2;
double ts = 0;
for (size_t i = 0; i < 10; i++) {
t1 = gettimeofday_sec();
f(s, c, n);
t2 = gettimeofday_sec();
double t3 = t2 - t1;
printf(" %f\n", t3);
ts += t3;
if (validate(s, 0xff & c, n) == false) {
printf("Validation false !\n");
}
}
double avg = ts / times;
printf(" Avg. %f\n", avg);
}
int main(void) {
static size_t const n = 32 * 1024 * 1024 + 1;
void* s = malloc(n);
printf("memset 0\n");
worker(memset0, s, 6, n);
printf("memset 0 no register\n");
worker(memset0_no, s, 6, n);
printf("memset 1\n");
worker(memset1, s, 6, n);
printf("memset 2\n");
worker(memset2, s, 6, n);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment