简体   繁体   English

如何在 C++ 中高效创建运行时可变大小数组?

[英]How to create a runtime variable-size array efficiently in C++?

Our library has a lot of chained functions that are called thousands of times when solving an engineering problem on a mesh every time step during a simulation.我们的库有很多链接函数,在模拟过程中的每个时间步解决网格上的工程问题时,这些函数都会被调用数千次。 In these functions, we must create arrays whose sizes are only known at runtime, depending on the application.在这些函数中,我们必须创建 arrays,其大小仅在运行时已知,具体取决于应用程序。 There are three choices we have tried so far, as shown below:目前我们尝试了三种选择,如下图:

void compute_something( const int& n )
{
    double fields1[n];               // Option 1.
    auto *fields2 = new double[n];   // Option 2.
    std::vector<double> fields3(n);  // Option 3.

    // .... a lot more operations on the field variables ....
}

From these choices, Option 1 has worked with our current compiler, but we know it's not safe because we may overflow the stack (plus, it's non standard).从这些选择中,选项 1与我们当前的编译器一起工作,但我们知道它不安全,因为我们可能会溢出堆栈(另外,它不是标准的)。 Option 2 and Option 3 are, on the other hand, safer, but using them as frequently as we do, is impacting the performance in our applications to the point that the code runs ~6 times slower than using Option 1 .另一方面,选项 2选项 3更安全,但像我们一样频繁地使用它们会影响我们应用程序的性能,以至于代码运行速度比使用选项 1慢约 6 倍。

What are other options to handle memory allocation efficiently for dynamic-sized arrays in C++?对于 C++ 中的动态大小的 arrays,还有哪些其他选项可以有效地处理 memory 分配? We have considered constraining the parameter n , so that we can provide the compiler with an upper bound on the array size (and optimization would follow);我们考虑过限制参数n ,以便我们可以为编译器提供数组大小的上限(随后将进行优化); however, in some functions, n can be pretty much arbitrary and it's hard to come up with a precise upper bound.然而,在某些函数中, n可以是任意的,很难得出一个精确的上限。 Is there a way to circumvent the overhead in dynamic memory allocation?有没有办法规避动态 memory 分配的开销? Any advice would be greatly appreciated.任何建议将不胜感激。

  1. Create a cache at startup and pre-allocate with a reasonable size.在启动时创建缓存并预分配合理的大小。
  2. Pass the cache to your compute function or make it part of your class if compute() is a method将缓存传递给您的计算 function,或者如果compute()是一种方法,则将其作为您的 class 的一部分
  3. Resize the cache调整缓存大小
std::vector<double> fields;
fields.reserve( reasonable_size );
...
void compute( int n, std::vector<double>& fields ) {       
     fields.resize(n);
     // .... a lot more operations on the field variables ....
}

This has a few benefits.这有一些好处。

  1. First, most of the time the size of the vector will be changed but no allocation will take place due to the exponential nature of std::vector's memory management.首先,由于 std::vector 的 memory 管理的指数性质,大多数时候向量的大小会改变但不会发生分配。

  2. Second, you will be reusing the same memory so it will be likely it will stay in cache.其次,您将重复使用相同的 memory,因此它很可能会保留在缓存中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM