在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 */
}

我不太清楚为什么在函数test()中使用volatile来避免优化。我在维基百科上看到volatile关键字表示一个值可能在不同的访问之间发生变化,即使它看起来没有被修改,但是,我不清楚在这个例子中使用volatile的原因,如果我们不使用volatile,会发生什么?

最佳答案

根据C标准,写入volatile变量是可观察的行为。(对我来说,在堆栈变量之后不使用的情况下没有太多意义,但它们是规则)。
编译器优化不允许改变程序的可观察行为,因此这会迫使编译器计算出result的值,以便将其分配给sink
如果不使用volatile编译器可能会将整个函数转换为no op,因为它没有可观察的行为。

10-08 09:27