Created
July 5, 2015 17:03
-
-
Save flandr/d2618063b898eb7067f4 to your computer and use it in GitHub Desktop.
Comparing __thread storage class specifier to pthread_getspecific on OS X 10.7+
This file contains 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
// Benchmarking pthread_getspecific vs __thread on OS X | |
// | |
// Compile with clang++ -g -O3 -std=c++11 | |
#include <stdio.h> | |
#include <pthread.h> | |
#include <chrono> | |
#include <cinttypes> | |
__thread int64_t foo; | |
inline int64_t thread_specifier() { | |
return foo; | |
} | |
pthread_key_t key; | |
inline int64_t pthread_getspecific() { | |
return reinterpret_cast<int64_t>(pthread_getspecific(key)); | |
} | |
template<typename Func> | |
std::chrono::microseconds run(Func const& func) { | |
auto start = std::chrono::system_clock::now(); | |
func(); | |
auto end = std::chrono::system_clock::now(); | |
return std::chrono::duration_cast<std::chrono::microseconds>(end - start); | |
} | |
int main(int argc, char **) { | |
const int kIters = 1E7; | |
pthread_key_create(&key, nullptr); | |
foo = 0; | |
int64_t val = 0; | |
auto t1 = run([&val]() -> void { | |
int ret = 0; | |
#pragma nounroll | |
for (int i = 0; i < kIters; ++i) { | |
ret += pthread_getspecific(); | |
asm volatile("" : "+r" (ret)); | |
} | |
val += ret; | |
}); | |
auto t2 = run([&val]() -> void { | |
int ret = 0; | |
#pragma nounroll | |
for (int i = 0; i < kIters; ++i) { | |
ret += thread_specifier(); | |
asm volatile("" : "+r" (ret)); | |
} | |
val += ret; | |
}); | |
printf("us/iter, pthread: %f ts: %f\n", t1.count() / (double) kIters, | |
t2.count() / (double) kIters); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment