gpt4 book ai didi

c++ - 为什么 4 个进程比 4 个线程好?

转载 作者:太空狗 更新时间:2023-10-29 23:25:34 27 4
gpt4 key购买 nike

void task1(void* arg) {
static volatile long res = 1;
for (long i = 0; i < 100000000; ++i) {
res ^= (i + 1) * 3 >> 2;
}
}

4 个线程,同时工作,在 30 秒内执行 task1 193 次。但是 4 个进程,同时工作,在 30 秒内执行 task1 348 次。为什么会有这么大的差异?我在 [Mac OS X 10.7.5,Intel Core i5(4 个逻辑内核)] 上对其进行了测试。想一想,Windows 和 Linux 中的相同差异。

最佳答案

res 变量是static,这意味着它由同一进程中的所有线程共享。这意味着在有四个线程的情况下,一个线程中 res 变量的每次修改都必须可供其他线程使用,这通常涉及总线上的某种锁定、 1 级缓存并在所有其他 CPU 中重新加载。

在四个进程的情况下,变量并没有真正被不同的进程共享,所以它们可以真正地并行运行,互不干扰。

请注意,主要区别不在于线程/进程,而在于在一种情况下每个人都访问同一个变量,而在另一种情况下他们访问不同的变量。此外,对于线程,真正的问题不是性能,而是最终结果可能不正确的事实:

res ^= x;

那不是原子操作,处理器会加载res的旧值,然后在寄存器中修改它并写回。如果没有同步原语,多个线程可以加载相同的值,独立修改它并写回变量,在这种情况下,一些线程的工作将被其他线程覆盖。最终结果将取决于不同线程的执行模式,而不是您的程序代码。

要模拟变量的非共享,您需要确保在线程中访问不同的缓存行。最简单的更改是从变量中删除 static 限定符,这样每个线程都会更新它自己的堆栈中的变量,该变量与其他线程的变量位于不同的内存地址中,并且希望映射到不同的缓存行。另一种选择是一起创建四个变量,但在它们之间添加足够的填充,以便它们分布到不同的缓存行:

struct padded_long {
volatile unsigned long res;
char [CACHE_LINE_SIZE - sizeof(long)]; // Find this in your processor documentation
};
void f(void *) {
static padded_long res[4];
// detect which thread is running based on the argument and use res[0]..res[3]
// for the different threads

关于c++ - 为什么 4 个进程比 4 个线程好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16635535/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com