Advertisement
Guest User

Untitled

a guest
Jan 30th, 2014
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.69 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/mman.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <omp.h>
  8. #include <x86intrin.h>
  9.  
  10. #define bind(f, arg) ({typeof(f(arg)) new(void) { return f(arg);} new;})
  11. #define bind2(f, arg, arg2) ({typeof(f(arg, arg2)) new(void) { return f(arg, arg2);} new;})
  12. #define bind3(f, arg, arg2, arg3) ({typeof(f(arg, arg2, arg3)) new(void) { return f(arg, arg2, arg3);} new;})
  13.  
  14. static inline void * alloc(uint64_t size, uint64_t flags) {
  15.   return mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | flags, 0, 0);
  16. }
  17.  
  18. typedef void*(*vpvf_t)(void);
  19.  
  20. #define GB (1024ul*1024*1024)
  21. #define KB (1024)
  22.  
  23. void bench_memcpy(uint64_t total, uint64_t pass, vpvf_t f) {
  24.   uint64_t i = (total/pass);
  25.   double start = omp_get_wtime();
  26.   do {f();} while(--i);
  27.   double time = omp_get_wtime() - start;
  28.   fprintf(stderr, "%fGB/s\n", ((total * 2)/GB)/time);
  29. }
  30.  
  31. void * memcpy_sphkavx(__m256i * to, __m256i * from, uint64_t n) {
  32.   typeof(from) from_end = ((void *)from + n), ret = to;
  33.   do {
  34.     _mm256_store_si256((to + 0), _mm256_load_si256(from + 0));
  35.     _mm256_store_si256((to + 1), _mm256_load_si256(from + 1));
  36.     _mm256_store_si256((to + 2), _mm256_load_si256(from + 2));
  37.     _mm256_store_si256((to + 3), _mm256_load_si256(from + 3));
  38.   } while((to += 4), (from += 4) != from_end);
  39.   return ret;
  40. }
  41.  
  42. void * memcpy_sphk(__m128i * to, __m128i * from, uint64_t n) {
  43.   typeof(from) from_end = ((void *)from + n), ret = to;
  44.   do {
  45.     _mm_stream_si128((to + 0), _mm_stream_load_si128(from + 0));
  46.     _mm_stream_si128((to + 1), _mm_stream_load_si128(from + 1));
  47.     _mm_stream_si128((to + 2), _mm_stream_load_si128(from + 2));
  48.     _mm_stream_si128((to + 3), _mm_stream_load_si128(from + 3));
  49.   } while((to += 4), (from += 4) != from_end);
  50.   return ret;
  51. }
  52.  
  53.  
  54. int main(void) {
  55.   vpvf_t alloc1gb = bind2(alloc, GB, MAP_POPULATE);
  56.   void * from = alloc1gb(), * to = alloc1gb();
  57.   uint64_t block_size = KB*KB*8, total = GB*2;
  58.   do {
  59.     fprintf(stderr, "\nBLOCK SIZE: %luKB\n", block_size/KB);
  60.     fprintf(stderr, "SPHK:\n");
  61.     if(block_size < (8*KB*KB)) {
  62.       bench_memcpy(total, block_size, bind3(memcpy_sphkavx, to, from, block_size));
  63.       bench_memcpy(total, block_size, bind3(memcpy_sphkavx, to, from, block_size));
  64.     } else {
  65.       bench_memcpy(total, block_size, bind3(memcpy_sphk, to, from, block_size));
  66.       bench_memcpy(total, block_size, bind3(memcpy_sphk, to, from, block_size));
  67.     }
  68.     fprintf(stderr, "memcpy:\n");
  69.     bench_memcpy(total, block_size, bind3(memcpy, to, from, block_size));
  70.     bench_memcpy(total, block_size, bind3(memcpy, to, from, block_size));
  71.   } while((block_size *= 2) != (GB*2));
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement