我正在尝试测试虚假共享对性能的影响。测试代码如下:
constexpr uint64_t loop = 1000000000;
struct no_padding_struct {
no_padding_struct() :x(0), y(0) {}
uint64_t x;
uint64_t y;
};
struct padding_struct {
padding_struct() :x(0), y(0) {}
uint64_t x;
char padding[64];
uint64_t y;
};
alignas(64) volatile no_padding_struct n;
alignas(64) volatile padding_struct p;
constexpr core_a = 0;
constexpr core_b = 1;
void func(volatile uint64_t* addr, uint64_t b, uint64_t mask) {
SetThreadAffinityMask(GetCurrentThread(), mask);
for (uint64_t i = 0; i < loop; ++i) {
*addr += b;
}
}
void test1(uint64_t a, uint64_t b) {
thread t1{ func, &n.x, a, 1<<core_a };
thread t2{ func, &n.y, b, 1<<core_b };
t1.join();
t2.join();
}
void test2(uint64_t a, uint64_t b) {
thread t1{ func, &p.x, a, 1<<core_a };
thread t2{ func, &p.y, b, 1<<core_b };
t1.join();
t2.join();
}
int main() {
uint64_t a, b;
cin >> a >> b;
auto start = std::chrono::system_clock::now();
//test1(a, b);
//test2(a, b);
auto end = std::chrono::system_clock::now();
cout << (end - start).count();
}
结果大多如下:
x86 x64
cores test1 test2 cores test1 test2
debug release debug release debug release debug release
0-0 4.0s 2.8s 4.0s 2.8s 0-0 2.8s 2.8s 2.8s 2.8s
0-1 5.6s 6.1s 3.0s 1.5s 0-1 4.2s 7.8s 2.1s 1.5s
0-2 6.2s 1.8s 2.0s 1.4s 0-2 3.5s 2.0s 1.4s 1.4s
0-3 6.2s 1.8s 2.0s 1.4s 0-3 3.5s 2.0s 1.4s 1.4s
0-5 6.5s 1.8s 2.0s 1.4s 0-5 3.5s 2.0s 1.4s 1.4s
我的 CPU 是intel core i7-9750h
. “core0”和“core1”是物理内核,“core2”和“core3”等也是。MSVC 14.24 被用作编译器。
由于有大量后台任务,记录的时间是几次运行中最好成绩的近似值。我认为这很公平,因为结果可以清楚地分组,0.1s~0.3s 的误差不会影响这样的划分。
Test2 很容易解释。x
和在y
不同的缓存行中一样,在 2 个物理内核上运行可以获得 2 倍的性能提升(在此可以忽略在单个内核上运行 2 个线程时的上下文切换成本),并且在具有 SMT 的一个内核上运行效率低于 2物理内核,受coffee-lake的吞吐量限制(相信Ryzen可以做得更好),并且比时间多线程更有效。似乎 64 位模式在这里更有效。
但是 test1 的结果让我很困惑。首先,在调试模式下,0-2、0-3 和 0-5 比 0-0 慢,这是有道理的。我对此进行了解释,因为某些数据被反复从 L1 移动到 L3 和 L3 到 L1,因为缓存必须在 2 个内核之间保持一致,而在单个内核上运行时它始终保持在 L1 中。但是这个理论与 0-1 对总是最慢的事实相冲突。从技术上讲,两个线程应该共享相同的 L1 缓存。0-1 的运行速度应该是 0-0 的 2 倍。
其次,在释放模式下,0-2、0-3、0-5 比 0-0 快,这反驳了上述理论。
最后,0-1 在 64 位和 32 位模式下的运行速度release
都比在debug
64 位和 32 位模式下要慢。这是我最不能理解的。我阅读了生成的汇编代码,没有发现任何有用的东西。