今天提出了这个问题(Prefetching double class member requires casting to char*?),并且接受的解决方案是预取成员函数的返回值,该函数通过引用返回成员变量。
然而,这让我很好奇 - 如果成员小于对象开头的缓存行偏移量,则调用对象的成员函数的行为不会隐式地将对象加载到缓存中,因此避免需要预先成员?如果不调用成员函数来预取对象会不会更有效(如我的回答所示)?
答案 0 :(得分:0)
调用对象的成员函数的行为是否隐式将对象加载到缓存中,从而无需预先缓存成员?
不完全。例如,看看这段代码。
#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;
}
鉴于double* dp = dc->getDoubleAddr();
为dc
,行NULL
上应该出现空指针错误。但是如果你编译并运行它,通常没有例外。
在由此构建的汇编代码中,所有对象方法(如dc->getDoubleAddr()
)都转换为标准函数,第一个参数是调用对象的地址(在本例中为dc
})。因此调用该函数不会导致空指针异常;参数仅为0x0。
然后,在代码中,getDoubleAddr返回对象内部的double的地址,给定对象的地址。这里不需要访问内存 - 程序已经知道对象类型,因此知道double_
的位置。它只返回对象的地址,加上它与char space[8]
的8字节偏移量,程序打印出0x8。