Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++_Caching - Fatal编程技术网

C++ 非连续数据的显式预取

C++ 非连续数据的显式预取,c++,caching,C++,Caching,我对图像的子区域做了很多操作。例如,如果我有一个100x100的图像,我可能想迭代这个图像并处理10x10像素的块。例如: for(each 10x10 block) { for(each pixel in the block) { do something } } 问题是,这些小块不是连续的内存块(即,图像像素按行主顺序存储,因此当我访问10x10块时,块中每一行的像素都是连续的,但块中的行不是连续的。是否可以采取任何措施来加快对这些块中像素的访问速度?还是不可能快速访问

我对图像的子区域做了很多操作。例如,如果我有一个100x100的图像,我可能想迭代这个图像并处理10x10像素的块。例如:

for(each 10x10 block)
{
  for(each pixel in the block)
  {
    do something
  }
}
问题是,这些小块不是连续的内存块(即,图像像素按行主顺序存储,因此当我访问10x10块时,块中每一行的像素都是连续的,但块中的行不是连续的。是否可以采取任何措施来加快对这些块中像素的访问速度?还是不可能快速访问数据结构的某个区域你喜欢这样吗

从我做的大量阅读中,它听起来像是第一次读取像素,因为循环中的唯一操作可能有用:

// First read the pixels
vector<float> vals(numPixels);
for(pixels in first row)
{
val[i] = pixels[i];
}

// Then do the operations on the pixels
for(elements of vals)
{
 doSomething(vals[i])
}

但我找不到任何实际的代码示例(相对于理论解释)这是真的吗?

gcc
有一个名为的内置函数。您可以将地址传递给该函数,在支持该函数的目标上,
gcc
将发出一条机器指令,导致该地址加载到缓存中,即使它没有立即使用


许多现代图像处理应用程序将图像存储在平铺中,而不是存储在行中(又称扫描线)您描述了。例如GIMP。因此,如果您可以控制映像的存储方式,则使用平铺方法可能会增加局部性,从而减少缓存未命中并提高性能。

gcc
有一个内置函数名为。您可以将地址传递给该函数,并且在支持该函数的目标上,
gcc
将l发出一条机器指令,导致该地址被加载到缓存中,即使它没有立即被使用


许多现代图像处理应用程序将图像存储在平铺中,而不是存储在行中(又称扫描线)您描述了。例如GIMP。因此,如果您可以控制图像的存储方式,则使用平铺方法可能会增加局部性,从而减少缓存未命中并提高性能。

将像素复制到向量中会将其放置到连续的内存区域中,如果它们适合缓存线,则通常会将其缓存。@chradcliffe但是如果它们只使用一次会有帮助吗?我认为@MvG对这个问题的答案是正确的。
\u builtin\u prefetch
将是正确的使用方法。我已经忘记了那个内置的。它将保存副本,并在您只使用一次值的情况下工作。将像素复制到向量中会将它们置为into一个连续的内存区域,如果它们适合缓存线,通常会被缓存。@chradcliffe但是如果它们只被使用一次,那会有什么帮助吗?我认为@MvG对此有正确的答案。
\u内置预取
将是正确的使用方法。我已经忘记了那个内置。它将保存副本并在ca中工作请注意,您只使用了一次该值。使用扫描线存储系统,我是否必须预取小图像块的每个地址?还是仅预取行块每行中第一个像素的地址?@DavidDoria,每当您预取一个字节的数据时,其整个缓存线都将加载到缓存中。这与图像的关系取决于在CPU架构、内存对齐等方面。一般来说,我会假设预加载每行的第一个像素就足够了。如果有疑问,请尝试这两种方法并对其进行基准测试。使用扫描线存储系统,我是否必须预取小图像块的每个地址?还是仅预取图像块每行的第一个像素的地址w block?@DavidDoria,每当预取一个字节的数据时,它的整个缓存线都会加载到缓存中。这与图像的关系取决于CPU架构、内存对齐等。一般来说,我认为预加载每行的第一个像素就足够了。如果有疑问,请尝试这两种方法并对其进行基准测试。
// Read and operate on the pixels
for(pixels in first row)
{
 doSomething(pixels[i])
}