Skip to content

Instantly share code, notes, and snippets.

@monocasa
Created August 16, 2017 04:33
Show Gist options
  • Save monocasa/4963ce7ad5b0284ffa3511bfc186b6cf to your computer and use it in GitHub Desktop.
Save monocasa/4963ce7ad5b0284ffa3511bfc186b6cf to your computer and use it in GitHub Desktop.
// Compiled with gcc -O2 -o magic magic.c
//
// Results in the following result on an i7-6820HQ
//
// $ ./magic
// slow: 0.019839 microseconds per write
// fast: 0.001779 microseconds per write
// magic: 0.001779 microseconds per write
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>
#define BUFFER_SIZE (1024)
#define MESSAGE_SIZE (31)
#define NUMBER_RUNS (1000000)
static inline double microtime() {
struct timeval tv;
gettimeofday(&tv, NULL);
return 1e6 * tv.tv_sec + tv.tv_usec;
}
int main() {
uint8_t message[MESSAGE_SIZE];
uint8_t buffer[BUFFER_SIZE * 2];
size_t offset;
double slow_start = microtime();
offset = 0;
for(int i = 0; i < NUMBER_RUNS; i++){
for(int j = 0; j < MESSAGE_SIZE; j++){
buffer[offset++ % BUFFER_SIZE] = message[j];
}
}
double slow_stop = microtime();
double fast_start = microtime();
offset = 0;
for(int i = 0; i < NUMBER_RUNS; i++){
memcpy(&buffer[offset], message, MESSAGE_SIZE);
offset = (offset + MESSAGE_SIZE) % BUFFER_SIZE;
}
double fast_stop = microtime();
double magic_start = microtime();
offset = 0;
for(int i = 0; i < NUMBER_RUNS; i++){
const int first_chunk_size = (BUFFER_SIZE - offset) >= MESSAGE_SIZE ?
MESSAGE_SIZE :
BUFFER_SIZE - offset;
memcpy(&buffer[offset], message, first_chunk_size);
offset = (offset + MESSAGE_SIZE) % BUFFER_SIZE;
if(first_chunk_size != MESSAGE_SIZE) {
// In here offset must equal 0
const int remaining = MESSAGE_SIZE - first_chunk_size;
memcpy(buffer, &message[first_chunk_size], remaining);
offset = remaining;
}
}
double magic_stop = microtime();
printf("slow: %f microseconds per write\n", (slow_stop - slow_start) / NUMBER_RUNS);
printf("fast: %f microseconds per write\n", (fast_stop - fast_start) / NUMBER_RUNS);
printf("magic: %f microseconds per write\n", (fast_stop - fast_start) / NUMBER_RUNS);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment