预取对象的成员变量,通过函数调用访问

Prefetching a member variable of an object, accessed via function call

今天有人问这个问题 (),公认的解决方案是预取成员函数的 return 值,即 return 通过引用编辑成员变量。

然而,这让我很好奇 - 如果成员小于对象开头的缓存行偏移量,那么调用对象的成员函数的行为是否会隐式地将对象加载到缓存中,从而避免了预缓存成员的需要?在不调用成员函数的情况下预取对象(如我的回答中所建议的那样)不是更有效吗?

Doesn't the act of calling the member function of the object implicitly load the object into the cache, thus obviating the need for precaching the member?

不完全是。例如,看这段代码。

#include <iostream>
using namespace std;

class DoubleContainer {
public:
    char space[8];
    double double_;
    double* getDoubleAddr();
};

double* DoubleContainer::getDoubleAddr()
{
    return &double_;
}

int main()
{
   DoubleContainer *dc = NULL;
   double* dp = dc->getDoubleAddr();
   cout << dp << endl;
   return 0;
}

鉴于 dcNULLdouble* dp = dc->getDoubleAddr(); 行似乎应该存在空指针错误。但是如果编译和运行这个,一般不会有异常。

在由此构建的汇编代码中,所有对象方法,如dc->getDoubleAddr(),都被转换为标准函数,第一个参数是调用对象的地址(在本例中,dc).所以调用函数不会导致空指针异常;参数只是 0x0.

然后,在代码中,给定对象的地址,getDoubleAddr returns 对象内部 double 的地址。这里不需要访问内存——程序已经知道对象类型,因此知道 double_ 的位置。它只是 returns 对象的地址,加上它相对于 char space[8] 的八字节偏移量,程序打印出 0x8.