Skip to content

Instantly share code, notes, and snippets.

@flandr
Created July 5, 2015 17:03
Show Gist options
  • Save flandr/d2618063b898eb7067f4 to your computer and use it in GitHub Desktop.
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+
// 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