Skip to content

Instantly share code, notes, and snippets.

@sssgun
Created March 29, 2018 07:12
Show Gist options
  • Save sssgun/3c659f8a44cd4f5b6fb11725262dfdcc to your computer and use it in GitHub Desktop.
Save sssgun/3c659f8a44cd4f5b6fb11725262dfdcc to your computer and use it in GitHub Desktop.
unrolling memcpy example
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <math.h>
#include <assert.h>
#define MAX_LOOPS 2000000
#define MAX_THREAD_COUNT 100
char* unroll_memcpy(char* dest, char* src, int size)
{
int i = 0;
unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src;
for (i = size >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (size & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (size & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (size & 1)
*d++ = *s++;
return dest;
}
int ex_01()
{
const char *tmp = "0123456789abcdefghijklmnopqrstuvwxyz";
char s_buf[128] = {0x00,};
char d_buf[128] = {0x00,};
memcpy(s_buf, tmp, (int)strlen((char *)tmp));
memcpy(s_buf+(int)strlen((char *)s_buf), tmp, (int)strlen((char *)tmp));
memcpy(d_buf, s_buf, (int)strlen((char *)s_buf));
printf("%s\n", d_buf);
return 0;
}
int ex_02()
{
const char *tmp = "0123456789abcdefghijklmnopqrstuvwxyz";
char s_buf[128] = {0x00,};
char d_buf[128] = {0x00,};
memcpy(s_buf, tmp, (int)strlen((char *)tmp));
memcpy(s_buf+(int)strlen((char *)s_buf), tmp, (int)strlen((char *)tmp));
unroll_memcpy(d_buf, (char *)s_buf, (int)strlen((char *)s_buf));
printf("%s\n", d_buf);
return 0;
}
void *consumer(void *ptr)
{
#ifdef USED_THREAD
int type = 1;
#else
int type = (int)*(int *)(ptr);
#endif
//printf("type %d\n", type);
switch (type) {
case 1:
ex_01();
break;
case 2:
ex_02();
break;
default:
break;
}
return;
}
int main(int argc, const char *const argv[])
{
int i, j, loop = 1, type = 1;
pthread_t thr[MAX_THREAD_COUNT];
struct timeval tv1, tv2;
if (argc > 1) {
loop = atoi(argv[1]);
if (argc == 2) {
type = atoi(argv[2]);
}
}
printf("loop %d, type %d\n", loop, type);
// Measuring time before starting the threads...
gettimeofday(&tv1, NULL);
for (j=0; j < loop; j++) {
#ifdef USED_THREAD
for (i=0; i < MAX_THREAD_COUNT; i++) {
pthread_create(&thr[i], NULL, consumer, &type);
}
for (i=0; i < MAX_THREAD_COUNT; i++) {
pthread_join(thr[i], NULL);
}
#else
consumer(&type);
#endif
}
// Measuring time after threads finished...
gettimeofday(&tv2, NULL);
if (tv1.tv_usec > tv2.tv_usec) {
tv2.tv_sec--;
tv2.tv_usec += 1000000;
}
printf("Result - %ld.%ld\n", tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment