mutex(상호 배제)는 로직 상에서 락을 걸어 충돌을 방지하는 기법이다.
그리고 atomic은 메모리 레벨에서 락을 걸어서 충돌을 막는 기법이다. 자세한 원리는 모름
아무튼 크게 보면 이 두가지 방법으로 멀티스레딩 시의 충돌을 방지할 수가 있다.
근데 Modern 이펙티브 C++에서 웬만하면 atomic을 쓰라고 하더라.
빠르다고.
그래서 얼마나 차이가 나나 테스트를 해봤다.
릴리즈모드에 x86이고, 단위는 나노초다.
그리고 최적화는 껐다.
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 | #include "Timer.h" #include #include #include #include #include constexpr auto COUNT = 10LL; int main(){Timer timer; /동기화 버전 준비/ long long sum = 0; std::mutex locker; std::vector<std::future> mutex_futures(COUNT); auto mutex_version = [&sum, &locker]() { locker.lock(); sum += std::random_device{}() % 10000; locker.unlock(); }; for (auto& e : mutex_futures) e = std::async(std::launch::deferred, mutex_version); /아토믹 버전 준비/ std::atomic<long long> sum2{ 0 }; std::vector<std::future> atomic_futures(COUNT); auto atomic_version = [&sum2]() { sum2 += std::random_device{}() % 10000; }; for(auto& e :atomic_futures) e = std::async(std::launch::deferred, atomic_version); /테스트 시작/timer.start(); for (auto& e : mutex_futures) e.get();auto time = timer.stop_and().get_nano(); timer.start(); for (auto& e : atomic_futures) e.get();auto time2 = timer.stop_and().get_nano(); std::cout << "반복횟수: " << COUNT << "\n\n"; std::cout << "수동 동기화: " << time << '\n' << "atomic 사용: " << time2;}Colored by Color Scripter | cs |
웬만해선 atomic이 더 빠른게 맞는것같다.