Created
August 16, 2017 04:33
-
-
Save monocasa/4963ce7ad5b0284ffa3511bfc186b6cf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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