在 C++ 中交换二维双数组

Posted

技术标签:

【中文标题】在 C++ 中交换二维双数组【英文标题】:Swap 2D Double Arrays in c++ 【发布时间】:2009-10-09 11:46:16 【问题描述】:

我有以下方法在 C++ 中交换两个双精度数组(双精度**)。分析代码,方法占运行时的7%......我在想这应该是一个低成本的操作,有什么建议吗?我是 C++ 新手,但我希望只是交换对数组的引用。

 62 void Solver::Swap(double** &v1, double** &v2)
 63 
 64         double** vswap = NULL;
 65         vswap = v2;
 66         v2 = v1;
 67         v1 = vswap;
 68 

【问题讨论】:

内置的 swap() 函数有什么问题? 我不知道...我是 C++ 新手。两者的表现相同。 【参考方案1】:

1) 确保您的函数是内联的。

2) 您可以就地交换,例如使用 XOR

3) 尝试强制编译器使用寄存器而不是堆栈来传递参数(即使在 x86 上存在大量寄存器压力,也值得尝试)——您可以使用标准的 register 关键字或使用 fastcall在 MS 的编译器上。

typedef double** TwoDimArray;

class Solver

  inline void Swap( register TwoDimArray& a, register TwoDimArray& b )
  
    a ^= b ^= a ^= b;
  
;

4) 不要为 vswap 之类的临时变量提供默认值。

【讨论】:

在其类定义中定义的成员函数是隐式内联的。 不错的解决方案,但 C++ 中的标识符不以数字“2DArray”开头。 我的错误,我写得太快了 :) 已更正。关于类内部方法的隐式内联,这是一个风格问题,我喜欢强调内联和虚拟关键字。 不确定我是否关注,a 和 b 来自哪里? 如果此更改使其更快,则您的编译设置有些可疑;您确定您使用的是高优化级别吗?通常,编译器会简单地忽略内联和寄存器,并且 XOR 交换不应该比寄存器-寄存器副本快得多;)【参考方案2】:

代码看起来不错。它只是一个指针赋值。这取决于该方法被调用了多少次。

【讨论】:

每次迭代都会调用一次以交换新旧数组。数组本身是 2x20000。数组的大小可能是个问题吗?【参考方案3】:

我猜你的分析器在这里有点困惑,因为这种方法实际上只交换两个指针,这非常便宜。除非这个方法被很多调用,否则它不应该出现在配置文件中。您的分析器是否告诉您此方法被调用的频率?

交换时您必须注意的一个问题是一个数组可能在缓存中而另一个不在缓存中(特别是如果它们很大),因此不断交换指针可能会破坏缓存,但这会显示为总体减速。

【讨论】:

数组都很大并且交换了很多。它正在我正在研究的 RK4 方法中使用。令我烦恼的是,交换的成本高于衍生评估。衍生品被计算了大约 2400 万次,而掉期只有 502 次,但掉期占 21%,衍生品仅占 13%。注意导数是相当简单的 atm... (t^3) 但都一样。 这也可能是由于您的交换被内联(您在优化的情况下运行,不是吗),这可能会使数字出现偏差。【参考方案4】:

您确定您分析了完全优化的代码吗?

你应该inline这个函数。

除此之外,我唯一看到的是您首先将NULL 分配给vswap,然后立即分配其他值-但这应该由优化器处理。

 inline void Solver::Swap(double** &v1, double** &v2)
 
   double** vswap = v2;
   v2 = v1;
   v1 = vswap;
 

但是,为什么不使用std::swap()

【讨论】:

我实际上不知道 std::swap... (oops) 另外,两者的执行速度相同。 Ty 将我指向 std::swap【参考方案5】:

不要假设 7% 意味着这个操作很慢 - 这取决于 else 正在发生的事情。

您可以只花费 1 纳秒的时间进行操作,并使其花费几乎 100% 的时间,而无需执行其他任何操作。

【讨论】:

以上是关于在 C++ 中交换二维双数组的主要内容,如果未能解决你的问题,请参考以下文章

在 MPI C++ 中传递大型二维数组

如何在 C++ 中获取二维动态数组的行数和列数

c++ 用vector 定义二维数组

如何交换二维数组中的行或列?

C++中如何在一个二维数组中查找某个值

C++二维数组(指针)做参数