atomic_vs_mutex.cpp
is copied from https://github.com/herumi/misc/blob/master/atomic_vs_mutex.cpp.
Last active
October 8, 2015 15:06
-
-
Save tell/0faf48c4445634ce7297 to your computer and use it in GitHub Desktop.
Atomic vs Mutex
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 <thread> | |
#include <mutex> | |
#include <atomic> | |
#define XBYAK_NO_OP_NAMES | |
#include <xbyak/xbyak_util.h> | |
const int N = 10000000; | |
void loop(void f()) | |
{ | |
for (int i = 0; i < N; i++) { | |
f(); | |
} | |
} | |
int ni; | |
void none_inc() { ni++; } | |
int none_get() { return ni; } | |
std::atomic<int> ai; | |
void atomic_inc() { ai++; } | |
int atomic_get() { return (int)ai; } | |
std::atomic<int> bi; | |
void atomic_inc2() { bi++; } | |
int mi; | |
std::mutex m; | |
void mutex_inc() | |
{ | |
std::lock_guard<std::mutex> al(m); | |
mi++; | |
} | |
int mutex_get() { return mi; } | |
int mi2; | |
std::mutex m2; | |
void mutex_inc2() | |
{ | |
std::lock_guard<std::mutex> al(m2); | |
mi2++; | |
} | |
void bench(const char *msg, void f(), int get(), void f2() = 0) | |
{ | |
Xbyak::util::Clock clk; | |
clk.begin(); | |
std::thread t1(loop, f); | |
std::thread t2(loop, f2 ? f2 : f); | |
t1.join(); | |
t2.join(); | |
clk.end(); | |
printf("%s=%d\n", msg, get()); | |
printf("clk=%f\n", clk.getClock() / double(N)); | |
} | |
int main() | |
{ | |
bench("none ", none_inc, none_get); | |
bench("atomic", atomic_inc, atomic_get); | |
bench("mutex ", mutex_inc, mutex_get); | |
bench("atomic not conflict", atomic_inc, atomic_get, atomic_inc2); | |
bench("mutex not conflict", mutex_inc, mutex_get, mutex_inc2); | |
} |
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 <cstdio> | |
#include <thread> | |
#include <boost/thread/barrier.hpp> | |
#define XBYAK_NO_OP_NAMES | |
#include <xbyak/xbyak_util.h> | |
const int T = 2; | |
const int N = 10000000; | |
int v[T + 2]; | |
int w[T + 2]; | |
void loop(void func(const int), const int id) | |
{ | |
for (int i = 0; i < N; i++) { | |
func(id); | |
} | |
} | |
void f(const int id) { | |
#if 0 | |
w[id] = v[id - 1] + v[id] + v[id + 1]; | |
v[id] = w[id - 1] + w[id] + w[id + 1]; | |
#else | |
v[id]++; | |
#endif | |
} | |
boost::barrier br(T); | |
void g(const int id) { | |
#if 0 | |
w[id] = v[id - 1] + v[id] + v[id + 1]; | |
br.wait(); | |
v[id] = w[id - 1] + w[id] + w[id + 1]; | |
br.wait(); | |
#else | |
v[id]++; | |
br.wait(); | |
#endif | |
} | |
void bench(const char *msg, void f(const int)) | |
{ | |
printf("%s\n", msg); | |
for (int i = 0; i < T + 2; i++) { | |
v[i] = i; | |
} | |
std::thread ts[T]; | |
Xbyak::util::Clock clk; | |
clk.begin(); | |
for (int i = 0; i < T; i++) { | |
ts[i] = std::thread(loop, f, i + 1); | |
} | |
for (int i = 0; i < T; i++) { | |
ts[i].join(); | |
} | |
clk.end(); | |
for (int i = 0; i < T + 2; i++) { | |
printf("v[%d]=%d\n", i, v[i]); | |
} | |
printf("clk=%f\n", clk.getClock() / double(N)); | |
} | |
int main() | |
{ | |
printf("hc = %u\n", std::thread::hardware_concurrency()); | |
bench("none", f); | |
bench("barrier", g); | |
} | |
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
#define XBYAK_NO_OP_NAMES | |
#include <xbyak/xbyak_util.h> | |
#include "throw-catch.hpp" | |
const int N = 1000000; | |
int numthrow, nothrow; | |
void loop(bool func(const int)) { | |
for (int i = 0; i < N; i++) { | |
if (func(i)) | |
numthrow++; | |
else | |
nothrow++; | |
} | |
} | |
void bench(const char *msg, bool func(const int)) { | |
numthrow = nothrow = 0; | |
Xbyak::util::Clock clk; | |
clk.begin(); | |
loop(func); | |
clk.end(); | |
const int sum = numthrow + nothrow; | |
const double ratio = double(numthrow) / double(sum); | |
#if 0 | |
printf("%s: numthrow=%d, nothrow=%d, ratio=%.3f, sum=%d\n", | |
msg, numthrow, nothrow, ratio, sum); | |
#else | |
printf("%s: ratio=%.3f\n", msg, ratio); | |
#endif | |
printf("clk=%f\n", clk.getClock() / double(N)); | |
} | |
int main() { | |
bench("none", Func<10>::normalfunc); | |
bench("none", Func<50>::normalfunc); | |
bench("none", Func<90>::normalfunc); | |
bench("throw-catch", Func<10>::catchfunc); | |
bench("throw-catch", Func<50>::catchfunc); | |
bench("throw-catch", Func<90>::catchfunc); | |
} | |
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
CC = $(CXX) | |
CPPFLAGS += -std=c++11 -pthread -O3 -I$(HOME)/include -I../xbyak | |
BOOST_SUFFIX = | |
WORKAROUND_LDLIBS = | |
ifeq ($(shell uname -s),Darwin) | |
BOOST_SUFFIX = -mt | |
endif | |
ifneq (,$(findstring Linux,$(shell uname -s))) | |
# See http://stackoverflow.com/questions/22593658/compiling-multithread-code-with-g-wl-no-as-needed-not-working | |
# and https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1228201 | |
WORKAROUND_LDLIBS = -Wl,--no-as-needed | |
endif | |
ifneq (,$(findstring CYGWIN,$(shell uname -s))) | |
BOOST_SUFFIX = -1_55 | |
endif | |
LDFLAGS += -L$(HOME)/lib -L/usr/bin | |
LDLIBS += $(addsuffix $(BOOST_SUFFIX),-lboost_thread -lboost_system) -lpthread $(WORKAROUND_LDLIBS) | |
TARGETS = atomic_vs_mutex barrier_thread main-throw-catch | |
all: $(TARGETS) | |
clean: | |
$(RM) $(TARGETS) | |
main-throw-catch.o: throw-catch.hpp | |
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
#pragma once | |
template<int Percentage> | |
struct Func { | |
static const int NumOfThrow = 10000; | |
static const int Total = NumOfThrow * 100 / double(Percentage); | |
static bool throwfunc(const int x) { | |
if ((x % Total) < NumOfThrow) { | |
throw std::runtime_error("an input is small."); | |
} | |
return false; | |
} | |
static bool catchfunc(const int x) | |
try { | |
return throwfunc(x); | |
} catch (...) { | |
return true; | |
} | |
static bool normalfunc(const int x) { | |
if ((x % Total) < NumOfThrow) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment