像 Intel 这样的编译器和 IBM's xlc可自动插入数据预取指令。
我有一些代码可以以牺牲可读性为代价来帮助预取。也就是说,有一个自然的代码分组,如
void foo(...){ // foo gets called frequently
...
char *myPtr = allocate(medium_size);
memset(myPtr,0,medium_size) // cache misses here. medium_size is ~ 1 cache line
// Miss occurs on first access by memset, but not enough
// data to ameliorate by any hardware prefetching
// triggered by memset. Basically foo() is called a lot
可以通过在过程中进一步插入分配并在之后立即发出预取指令来减轻 memset 引起的缓存未命中的成本,在它和 memset 之间有足够的指令以便有时间让数据被带入缓存。在我的例子中,计算 medium_size 的代码在过程中进一步推进时会变得有点困惑,从而降低可读性。
如果编译器可以为我重新安排代码以使预取变得有值(value)(可能在 PGO 的支持下),那么我可以两全其美。
到目前为止,Visual Studio 似乎只支持内在函数,即手动放置预取指令。我错了吗?
针对问题的澄清更新:
问:编译器如何改进上面的代码? A:上面的代码只是为了让大家大致了解一下所涉及的内容。实际代码更复杂,但归结为分配和存储。读取由 memset 在写入内存时完成。在某些架构上,这可能不会触发缓存未命中,但在 x86 上,它显然会触发(根据 vTune)(由下面的 markgz 回答)。
问:仅仅使用 memset 还不够吗? memset 的内存访问模式是高度可预测的,硬件预取机制应该处理它。 答:是的,总的来说这是真的,我在解释更多上下文方面做得不好。 包含 memset 的例程 (foo) 被调用得非常频繁,它是触发缓存未命中的 memset 的第一次内存访问。 memset 没有足够的数据通过预取来改善这种未命中,因此我需要在调用 memset 之前进行预取。
最佳答案
是的,你可以使用
void _mm_prefetch(char*,int)
关于c++ - Visual Studio C/C++ 是否支持自动软件预取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15514054/