在CSAPP2e中,当演示“记忆山”时,作者使用了以下代码:
double data[MAXELEMS]
/* $begin mountainfuns */
void test(int elems, int stride) /* The test function */
{
int i, result = 0;
volatile int sink;
for (i = 0; i < elems; i += stride)
result += data[i];
sink = result; /* So compiler doesn't optimize away the loop */
}
/* Run test(elems, stride) and return read throughput (MB/s) */
double run(int size, int stride, double Mhz)
{
double cycles;
int elems = size / sizeof(int);
test(elems, stride); /* warm up the cache */
cycles = fcyc2(test, elems, stride, 0); /* call test(elems,stride) */
return (size / stride) / (cycles / Mhz); /* convert cycles to MB/s */
}
我不太清楚为什么我们使用volatile来避免函数test()中的优化。我在维基百科上看到volatile关键字表示某个值可能在不同的访问之间发生变化,即使它似乎没有被修改,但是,我不清楚在这个例子中使用volatile的原因,如果我们不使用volatile会发生什么?
答案 0 :(得分:3)
根据C标准,写入core
变量是可观察行为。 (对于我来说,对于我之后没有使用过的堆栈变量,它没有多大意义,但它们是规则)。
不允许编译器优化改变程序的可观察行为,因此这会强制编译器计算出volatile
的值,以便将其分配给result
。
如果你不使用sink
,编译器可能会将整个函数转换为无操作,因为它没有可观察的行为。