Created
March 29, 2018 07:12
-
-
Save sssgun/3c659f8a44cd4f5b6fb11725262dfdcc to your computer and use it in GitHub Desktop.
unrolling memcpy example
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
| #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