- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
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/
我是一名优秀的程序员,十分优秀!