res
变量是,这static
意味着它被同一进程中的所有线程共享。这意味着在四个线程的情况下,res
一个线程中变量的每次修改都必须对其他线程可用,这通常涉及总线上的某种锁定、一级缓存的无效和所有其他线程的重新加载中央处理器。
在四个进程的情况下,变量并没有真正被不同的进程共享,因此它们可以真正并行运行而不会相互干扰。
请注意,主要区别不是线程/进程,而是在一种情况下每个人都访问相同的变量而在另一种情况下他们访问不同的变量这一事实。此外,在线程的情况下,真正的问题不是性能,而是最终结果可能不正确的事实:
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