如何使用Armadillo Columns / Rows对同一列中的访问执行优化计算

时间:2015-03-14 09:56:33

标签: arrays performance indexing armadillo

在犰狳中操纵索引的最佳方法是什么?我的印象是它大量使用模板表达式以避免临时性,但我没有看到这些加速。

直接数组索引仍然是接近依赖同一数组中连续元素的计算的最佳方法吗?

请记住,我希望将来使用TBB :: parallel_for来并行化这些计算(在这种情况下,从可维护性的角度来看,使用直接访问可能更简单吗?)这些计算发生在紧密循环中,我希望尽可能地让它们变得最佳。

   ElapsedTimer timer;
   int n = 768000;
   int numberOfLoops = 5000;
   arma::Col<double> directAccess1(n);
   arma::Col<double> directAccess2(n);
   arma::Col<double> directAccessResult1(n);
   arma::Col<double> directAccessResult2(n);
   arma::Col<double> armaAccess1(n);
   arma::Col<double> armaAccess2(n);
   arma::Col<double> armaAccessResult1(n);
   arma::Col<double> armaAccessResult2(n);
   std::valarray<double> valArrayAccess1(n);
   std::valarray<double> valArrayAccess2(n);
   std::valarray<double> valArrayAccessResult1(n);
   std::valarray<double> valArrayAccessResult2(n);
   // Prefil
   for (int i = 0; i < n; i++) {
      directAccess1[i] = i;
      directAccess2[i] = n - i;
      armaAccess1[i] = i;
      armaAccess2[i] = n - i;
      valArrayAccess1[i] = i;
      valArrayAccess2[i] = n - i;
   }
   timer.Start();
   for (int j = 0; j < numberOfLoops; j++) {
      for (int i = 1; i < n; i++) {
         directAccessResult1[i] = -directAccess1[i] / (directAccess1[i] + directAccess1[i - 1]) *  directAccess2[i - 1];
         directAccessResult2[i] = -directAccess1[i] / (directAccess1[i] + directAccess1[i]) *  directAccess2[i];
      }
   }
   timer.StopAndPrint("Direct Array Indexing Took");
   std::cout << std::endl;

   timer.Start();
   for (int j = 0; j < numberOfLoops; j++) {
      armaAccessResult1.rows(1, n - 1) = -armaAccess1.rows(1, n - 1) / (armaAccess1.rows(1, n - 1) + armaAccess1.rows(0, n - 2)) % armaAccess2.rows(0, n - 2);
      armaAccessResult2.rows(1, n - 1) = -armaAccess1.rows(1, n - 1) / (armaAccess1.rows(1, n - 1) + armaAccess1.rows(1, n - 1)) % armaAccess2.rows(1, n - 1);
   }
   timer.StopAndPrint("Arma Array Indexing Took");
   std::cout << std::endl;

   timer.Start();
   for (int j = 0; j < numberOfLoops; j++) {
      for (int i = 1; i < n; i++) {
         valArrayAccessResult1[i] = -valArrayAccess1[i] / (valArrayAccess1[i] + valArrayAccess1[i - 1]) *  valArrayAccess2[i - 1];
         valArrayAccessResult2[i] = -valArrayAccess1[i] / (valArrayAccess1[i] + valArrayAccess1[i]) *  valArrayAccess2[i];
      }
   }
   timer.StopAndPrint("Valarray Array Indexing Took:");
   std::cout << std::endl;

在vs release模式下(/ 02 - 为了避免犰狳数组索引检查),它们产生以下时间:

Started Performance Analysis!
Direct Array Indexing Took: 37.294 seconds elapsed
Arma Array Indexing Took: 39.4292 seconds elapsed
Valarray Array Indexing Took:: 37.2354 seconds elapsed

1 个答案:

答案 0 :(得分:0)

您的直接代码已经非常优化,因此表达式模板在这里无济于事。

但是,您可能希望确保编译器中的优化级别实际启用自动向量化(gcc中为-O3)。其次,在包含Armadillo标题之前,您可以通过#define ARMA_NO_DEBUG获得一些额外的速度。这将关闭所有运行时检查(例如element access的绑定检查),但在完全调试程序之前不建议这样做。