c++ - 优化此代码块

标签 c++ optimization loops

for (int i = 0; i < 5000; i++)
   for (int j = 0; j < 5000; j++)
   {
      for (int ii = 0; ii < 20; ii++)
          for (int jj = 0; jj < 20; jj++)
           {
               int num = matBigger[i+ii][j+jj];
               // Extract range from this.
               int low = num & 0xff;
               int high = num >> 8;
               if (low < matSmaller[ii][jj] && matSmaller[ii][jj] > high)
                  // match found
           }
   }

机器是x86_64, 32kb L1 cahce, 256 Kb L2 cache.

关于如何优化此代码的任何指示?

编辑 原始问题的一些背景:Fastest way to Find a m x n submatrix in M X N matrix

最佳答案

我要尝试的第一件事是移动 iijji 外循环和 j循环。这样您就可以使用 matSmaller 的相同元素。 i 的 2500 万次迭代和 j循环,这意味着您(或编译器,如果幸运的话)可以将对它们的访问提升到这些循环之外:

for (int ii = 0; ii < 20; ii++)
  for (int jj = 0; jj < 20; jj++)
    int smaller = matSmaller[ii][jj];
    for (int i = 0; i < 5000; i++)
      for (int j = 0; j < 5000; j++) {
        int num = matBigger[i+ii][j+jj];
        int low = num & 0xff;
        if (low < smaller && smaller > (num >> 8)) {
          // match found
        }
      }

这可能会更快(由于对 matSmaller 数组的访问较少),也可能会更慢(因为我已经更改了对 matBigger 数组的访问模式,而且我可能已经它不太缓存友好)。类似的替代方法是移动 ii外循环 ij和提升matSmaller[ii] , 但保留 jj在里面循环。经验法则是在内部循环中递增多维数组的 last 索引比之前的索引对缓存更友好。所以我们“更高兴”修改jjj比我们修改 iii .

我会尝试的第二件事 - matBigger 的类型是什么?看起来其中的值只有 16 位,所以尝试将其作为 int(u)int16_t .前者可能更快,因为对齐 int访问速度很快。后者可能更快,因为在任何时候都有更多的数组适合缓存。

通过对 smaller 的一些早期分析,您可以考虑一些更高层次的事情:例如,如果它是 0那么你不需要检查 matBigger对于 ii 的值和 jj ,因为 num & 0xff < 0总是假的。

为了比“猜测事物并查看它们是否更快”做得更好,您首先需要知道哪条线路 HitTest ,这意味着您需要一个分析器。

关于c++ - 优化此代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10618383/

相关文章:

matlab - 将元素 append 到数组的最快方法是什么?

javascript - jQuery 执行缓慢的常见原因以及如何优化代码?

c - Do While 循环总是在第一次循环后退出

c++ - 扩展初始化列表仅适用于

c++ - 错误的函数调用 "IOCTL_DISK_GET_DRIVE_LAYOUT_EX"

c++ - 通过 using 指令可见的声明的名称隐藏

c++ - 虚函数调用优化

c++ - 正在生成缓慢的 vpermpd 指令;为什么?

c++ - 在 C++ 中生成随机数学运算符

loops - Nightmare 如何循环选择选择器