Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 便携式显式预取_C++_C_Portability_Prefetch - Fatal编程技术网

C++ 便携式显式预取

C++ 便携式显式预取,c++,c,portability,prefetch,C++,C,Portability,Prefetch,我需要一种简单且可移植的方法来显式地预取数据。我不想使用任何特定编译器或平台的特定功能,只想使用足够通用的功能来跨不同的平台和编译器工作 我想到的一个非常简单的解决方案是将一个字节/int从内存位置移动到一个寄存器中,“应该”将该内存段带到CPU缓存中以填充一行,至少我在逻辑上是这样假设的。但也许不会那么容易?一种可能性是,如果数据未在特定范围内访问,编译器将优化操作,因此不会发生预取。一般来说,预取和内存加载不是完全相同的操作。有几个基本区别: 预取无效地址不会产生故障,而尝试读取、写入或执行

我需要一种简单且可移植的方法来显式地预取数据。我不想使用任何特定编译器或平台的特定功能,只想使用足够通用的功能来跨不同的平台和编译器工作


我想到的一个非常简单的解决方案是将一个字节/int从内存位置移动到一个寄存器中,“应该”将该内存段带到CPU缓存中以填充一行,至少我在逻辑上是这样假设的。但也许不会那么容易?一种可能性是,如果数据未在特定范围内访问,编译器将优化操作,因此不会发生预取。

一般来说,预取和内存加载不是完全相同的操作。有几个基本区别:

  • 预取无效地址不会产生故障,而尝试读取、写入或执行无效地址会产生故障(当然,如果CPU有MPU/MMU)
  • 预取可以用于读取和/或写入,而将一个字节读入寄存器就是将一个字节读入寄存器
  • 您可以(理论上)在预取时指定内存位置
  • CPU可能具有与内存加载指令不同的用于预取的特殊指令
  • 所以只需坚持使用
    \u内置预取
    ,让编译器来完成繁重的工作

    另外,请记住,优化编译器可能会自动生成预取指令。我想如果他们这样做了,那么你必须确保你不会干预

    另一件有趣的事情是,一般来说,显式预取不会提高性能,反而会略微降低性能。请参阅,以了解为什么从Linux内核中完全删除预取的详细信息和解释


    希望能有帮助。祝你好运

    你需要注意编译器优化内存读取,因为它会认为他们没有做任何事情。在C或C++中没有可移植的方式,因为不能保证你正在编译一个登记机上的本机代码。例如,解释C++和编译到JVM- <代码> MyMyPrExcCy应该相当便携。与MSDN page所说的相反,SSE Intrinsic不是Microsoft特有的,至少在一些最流行的编译器(GCC、Clang、Intel、MSVC)上可用。我想在处理当前节点时预取下一个节点,我不认为编译器看起来“更远”。这些节点在内存中不是按顺序排列的,因此我不希望CPU硬件预取程序也能起到任何作用。@ddriver:不要猜测,进行更改并配置文件。正如内核开发人员已经证明的那样,在一般情况下,手动预取会降低性能(请阅读本文)。所以这是一个有害的错误优化。@ddriver以非可移植的方式(
    \u内置\u预取
    等)进行优化,是否会导致速度加快?除此之外,考虑最便携的方式没有什么意义。在我有限的经验中,每次我使用手动预取时,结果都比较慢,或者最多是类似的。在那个特定的场景中,我使用
    \uuu内置预取
    得到了明显的提升,但是我同意,过度使用任何东西通常都是有害的。@ddriver,别忘了CPU在代码之前运行(至少在其队列能够容纳的范围内),因此,一旦知道下一个节点的地址,它很可能会被实际负载获取,因此预取是多余的。您是否尝试过提前预取多个节点?