测试了下c++下atomic<int>递增的性能,cpu13900k,大小核
从下面看到atomic 变量在cpu之间颠簸的情况下, 是普通递增指令的200倍, 加锁, 解锁, 假设线程8个, 那么大概率atomic变量不在正在运行的cpu上, 那么就会耗费400时钟周期.
8个线程:
Atomic counter: 800000000 Time: 6192 ms
Non-atomic counter: 128105858 Time: 24 ms
1个线程
Atomic counter: 100000000 Time: 335 ms
Non-atomic counter: 100000000 Time: 18 ms
可以看到atomic没有竞争的情况下大概是普通递增指令的20倍, 多线程有颠簸的情况下是250倍
#include <iostream>
#include <atomic>
#include <chrono>
#include <thread>
#include <vector>
const int NUM_ITERATIONS = 1000000;
const int NUM_THREADS = 8;
void atomic_increment(std::atomic<int>& counter) {
for (int i = 0; i < NUM_ITERATIONS; ++i) {
++counter;
}
}
void non_atomic_increment(volatile int& counter) {
for (int i = 0; i < NUM_ITERATIONS; ++i) {
++counter;
}
}
int main() {
std::atomic<int> atomic_counter(0);
volatile int non_atomic_counter = 0;
auto start_atomic = std::chrono::high_resolution_clock::now();
std::vector<std::thread> atomic_threads;
for (int i = 0; i < NUM_THREADS; ++i) {
atomic_threads.push_back(std::thread(atomic_increment, std::ref(atomic_counter)));
}
for (auto& t : atomic_threads) {
t.join();
}
auto end_atomic = std::chrono::high_resolution_clock::now();
auto atomic_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_atomic - start_atomic).count();
auto start_non_atomic = std::chrono::high_resolution_clock::now();
std::vector<std::thread> non_atomic_threads;
for (int i = 0; i < NUM_THREADS; ++i) {
non_atomic_threads.push_back(std::thread(non_atomic_increment, std::ref(non_atomic_counter)));
}
for (auto& t : non_atomic_threads) {
t.join();
}
auto end_non_atomic = std::chrono::high_resolution_clock::now();
auto non_atomic_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_non_atomic - start_non_atomic).count();
std::cout << "Atomic counter: " << atomic_counter << " Time: " << atomic_duration << " ms" << std::endl;
std::cout << "Non-atomic counter: " << non_atomic_counter << " Time: " << non_atomic_duration << " ms" << std::endl;
return 0;
}
CXX = g++
CXXFLAGS = -std=c++11 -O3 -pthread
TARGET = atomic_test
OBJS = main.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS)
main.o: main.cpp
$(CXX) $(CXXFLAGS) -c main.cpp
clean:
rm -f $(OBJS) $(TARGET)
测试代码和makefile 让chatgpt-4写的
--
修改:stub FROM 114.242.248.*
FROM 61.48.14.*