预取双 class 成员需要强制转换为 char*?

Prefetching double class member requires casting to char*?

我有一个 class,我正在使用它 _mm_prefetch() 来预先请求包含 class 成员的高速缓存行,类型为 double:

class MyClass{

    double getDouble(){
        return dbl;
    }

    //other members
    double dbl;
    //other members
};

_mm_prefetch()签名为:

void _mm_prefetch (char const* p, int i)

但是当我这样做时:

_mm_prefetch((char*)(myOb.getDouble()), _MM_HINT_T0);

GCC 抱怨:

error: invalid cast from type 'double' to type 'char*'

那么如何预取这个 class 成员?

如果您从您链接到的网站阅读了 _mm_prefetch() 的描述,则有:

void _mm_prefetch (char const* p, int i)

Fetch the line of data from memory that contains address p to a location in the cache heirarchy specified by the locality hint i.

所以你需要传递你想要的变量的地址。为此,您需要将 class 成员的引用地址或指向它的指针传递给函数。

最简单的解决方案是将 getDouble() 更改为 return 引用,然后您可以使用:

_mm_prefetch((char*)(&myOb.getDouble()), _MM_HINT_T0);

_mm_prefetch 将内存地址处的缓存行加载到缓存中。尝试将 double 转换为指针是行不通的,因为它们不是兼容的类型。此外,您不能简单地在 getDouble 的 return 值的地址上调用 _mm_prefetch,因为它不会是您要查找的实例的地址,而是本地地址或临时的(大概已经 'close' 到处理器)。此外,简单地调用 getDouble 的行为将加载地址,因为您正在访问函数内的成员。

最有可能的是,您最好的选择(取决于 MyClass 的大小和目标缓存行的大小)是将整个对象加载到缓存中,如下所示:

_mm_prefetch(&myOb, _MM_HINT_T0);

当您可以在对内存地址执行的操作之前稍微提前进行预取时,预取通常也是最有效的。例如,做:

_mm_prefetch(&myOb, _MM_HINT_T0);
myObj.getDouble();

不会提高性能(事实上,它可能会降低性能)。