犰狳不执行交换优化

时间:2018-11-10 22:00:50

标签: c++ armadillo

如何交换犰狳对象,例如arma::vec,而不交换内容?

void f5()
{
  arma::vec x(10);
  arma::vec y(10);
  std::cout << &x[2] << ", " << &y[2] << "\n";
  x.swap(y);
  std::cout << &x[2] << ", " << &y[2];
}

上面的代码输出

0x24fbe50, 0x24fbef0
0x24fbe50, 0x24fbef0

谢谢!

2 个答案:

答案 0 :(得分:2)

@ OZ17的答案的小扩展。 犰狳似乎在本地存储mem_local且大小小于16的数据,并在mem指出的区域中存储较大的数据

From GDB:
> p x
{
  <arma::Mat<double>> = {
    <arma::Base<double, arma::Mat<double> >> = {
    <arma::Base_inv_yes<arma::Mat<double> >> = {<No data fields>}, 
    <arma::Base_eval_Mat<double, arma::Mat<double> >> = {<No data fields>}, 
    <arma::Base_trans_default<arma::Mat<double> >> = {<No data fields>}, <No data fields>}, 
    members of arma::Mat<double>: 
    n_rows = 1, 
    n_cols = 10, 
    n_elem = 10, 
    vec_state = 2, 
    mem_state = 0, 
    mem = 0x7fffffffb830, 
    mem_local = {0 <repeats 16 times>},   
    static is_col = false, 
    static is_row = false
  }, 
  members of arma::Row<double>: 
  static is_col = false, 
  static is_row = false
}

和一个可视化的小例子:

arma::rowvec x(10,arma::fill::ones);
arma::rowvec y(10,arma::fill::zeros);
std::cout << "Size=10" << std::endl;
std::cout << "&x=" << x.memptr() << ", x[0..4]=" << x.subvec(1,5);
std::cout << "&y=" << y.memptr() << ", y[0..4]=" << y.subvec(1,5);
x.swap(y);
std::cout << "x.swap(y)" << std::endl;
std::cout << "&x=" << x.memptr() << ", x[0..4]=" << x.subvec(1,5);
std::cout << "&y=" << y.memptr() << ", y[0..4]=" << y.subvec(1,5);

arma::rowvec x2(17,arma::fill::ones);
arma::rowvec y2(17,arma::fill::zeros);
std::cout << "\nSize=17" << std::endl;
std::cout << "&x=" << x2.memptr() << ", x[0..4]=" << x2.subvec(1,5);
std::cout << "&y=" << y2.memptr() << ", y[0..4]=" << y2.subvec(1,5);
x2.swap(y2);
std::cout << "x.swap(y)" << std::endl;
std::cout << "&x=" << x2.memptr() << ", x[0..4]=" << x2.subvec(1,5);
std::cout << "&y=" << y2.memptr() << ", y[0..4]=" << y2.subvec(1,5);

该示例的输出显示,两种情况下都交换了内容,但对于较小的数组,它已交换了本地内存区域,对于较大的情况,它已交换了内存指针。

Size=10
&x=0x7fffffffb830, x[0..4]=   1.0000   1.0000   1.0000   1.0000   1.0000
&y=0x7fffffffb8e0, y[0..4]=        0        0        0        0        0
x.swap(y)
&x=0x7fffffffb830, x[0..4]=        0        0        0        0        0
&y=0x7fffffffb8e0, y[0..4]=   1.0000   1.0000   1.0000   1.0000   1.0000

Size=17
&x=0x5555557d7fd0, x[0..4]=   1.0000   1.0000   1.0000   1.0000   1.0000
&y=0x5555557d8060, y[0..4]=        0        0        0        0        0
x.swap(y)
&x=0x5555557d8060, x[0..4]=        0        0        0        0        0
&y=0x5555557d7fd0, y[0..4]=   1.0000   1.0000   1.0000   1.0000   1.0000

答案 1 :(得分:0)

就像犰狳的交换在内部是小于特定数组大小的memcpy(根据op <= 16)。