显式预取非连续数据

时间:2012-10-20 16:26:04

标签: c++ caching

我在图像的子区域上做了很多操作。例如,如果我有一个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])
}

与我正在做的事情同时只是:

// Read and operate on the pixels
for(pixels in first row)
{
 doSomething(pixels[i])
}

但我无法找到任何实际的代码示例(与理论解释相比)。这有什么道理吗?

1 个答案:

答案 0 :(得分:1)

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

许多现代图像处理应用程序将图像存储在 tiles 中,而不是您描述的(a.k.a。* scanlines)。例如。 GIMP does that。因此,如果您可以控制图像的存储方式,那么使用平铺方法可能会增加局部性,从而减少缓存未命中并提高性能。