Advertisement
Guest User

Cross Cache Line Locked Add

a guest
Jan 24th, 2017
794
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.04 KB | None | 0 0
  1. #include <cassert>
  2. #include <iostream>
  3. #include <stdint.h>
  4. #include <sys/stat.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <vector>
  8.  
  9. constexpr int CacheLineSize = 64;
  10.  
  11. using namespace std;
  12.  
  13. class WallClockTimer {
  14. public:
  15.   struct timeval t1, t2;
  16.   WallClockTimer() : t1(), t2() {
  17.     gettimeofday(&t1, 0);
  18.     t2 = t1;
  19.   }
  20.   void reset() {
  21.     gettimeofday(&t1, 0);
  22.     t2 = t1;
  23.   }
  24.   int elapsed() {
  25.     return (t2.tv_sec * 1000 + t2.tv_usec / 1000) -
  26.            (t1.tv_sec * 1000 + t1.tv_usec / 1000);
  27.   }
  28.   int split() {
  29.     gettimeofday(&t2, 0);
  30.     return elapsed();
  31.   }
  32. };
  33.  
  34. template <class T> void locked_add(T *out, T in) {
  35.   asm volatile("lock add %0, %1" : "+r"(in), "+m"(*out) : : "memory", "cc");
  36. }
  37.  
  38. template <class T> void runtest() {
  39.   size_t N = 100 * 1000;
  40.   int repeat = 20;
  41.   WallClockTimer timer;
  42.   const bool paranoid = false;
  43.   cout << " processing word of size " << sizeof(T) << endl;
  44.   for (unsigned int offset = 0; offset < CacheLineSize + sizeof(T); ++offset) {
  45.     char cache[CacheLineSize + sizeof(T)];
  46.     unsigned long long absolute_offset = reinterpret_cast<unsigned long long>(&cache[offset]);
  47.     cout << " absolute offset = " << (absolute_offset % CacheLineSize) << endl;
  48.     if (absolute_offset % CacheLineSize > (absolute_offset + sizeof(T) - 1) % CacheLineSize) {
  49.       cout << " spans cache line" << endl;
  50.     }
  51.     int sumt = 0;
  52.     for (int k = 0; k < repeat; ++k) {
  53.       timer.reset();
  54.       T *val = reinterpret_cast<T *>(&cache[offset]);
  55.       *val = 1;
  56.       for (size_t i = 0; i < N; ++i) {
  57.         locked_add(val, static_cast<T>(i) * (*val) + 33);
  58.       }
  59.       int time = timer.split();
  60.       sumt += time;
  61.     }
  62.     cout << " average time for offset " << (absolute_offset % CacheLineSize) << " is "
  63.          << sumt * 1.0 / repeat << endl;
  64.     cout << endl;
  65.   }
  66. }
  67.  
  68. int main() {
  69.   runtest<int>();
  70.   cout << sizeof(int) << endl;
  71.   runtest<long>();
  72.   cout << sizeof(long) << endl;
  73.   runtest<long long>();
  74.   cout << sizeof(long long) << endl;
  75.  
  76.   return 0;
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement