相关疑难解决方法(0)

C++替代C99 VLA(目标:保持性能)

我正在移植一些C99代码,这些代码大量使用可变长度数组(VLA)到C++.

我用一个在堆上分配内存的数组类替换了VLA(堆栈分配).业绩受到巨大影响,放缓了3.2倍(见下面的基准). 我可以在C++中使用什么快速的VLA替换?我的目标是在重写C++代码时尽量减少性能损失.

向我建议的一个想法是编写一个数组类,其中包含类中的固定大小的存储(即可以是堆栈分配)并将其用于小型数组,并自动切换到更大数组的堆分配.我的实现是在帖子的最后.它工作得相当好,但我仍然无法达到原始C99代码的性能.为了接近它,我必须将这个固定大小的存储空间(MSL下面)增加到我不熟悉的尺寸.即使对于许多不需要它的小型数组,我也不想在堆栈上分配太大的数组,因为我担心它会触发堆栈溢出.C99 VLA实际上不太容易发生这种情况,因为它永远不会使用比所需更多的存储空间.

我遇到了std::dynarray,但我的理解是它没有被标准接受(但是?).

我知道clang和gcc在C++中支持VLA,但我也需要它与MSVC一起工作.事实上,更好的可移植性是重写为C++的主要目标之一(另一个目标是将程序(最初是命令行工具)转换为可重用的库).


基准

MSL指的是我在其上切换到堆分配的数组大小.我对1D和2D数组使用不同的值.

原始C99代码:115秒.
MSL = 0(即堆分配):367秒(3.2x).
1D-MSL = 50,2D-MSL = 1000:187秒(1.63x).
1D-MSL = 200,2D-MSL = 4000:143秒(1.24x).
1D-MSL = 1000,2D-MSL = 20000:131(1.14x).

增加MSL进一步提高性能,但最终程序将开始返回错误的结果(我假设由于堆栈溢出).

这些基准测试是在OS X上使用clang 3.7,但是gcc 5显示了非常相似的结果.


这是我使用的当前"小向量"实现.我需要1D和2D矢量.我切换到大小超过堆分配MSL.

template<typename T, size_t MSL=50>
class lad_vector {
    const size_t len;
    T sdata[MSL];
    T *data;
public:
    explicit lad_vector(size_t len_) : len(len_) {
        if (len <= MSL)
            data = &sdata[0];
        else
            data = new …
Run Code Online (Sandbox Code Playgroud)

c++ arrays performance variable-length-array stack-allocation

36
推荐指数
3
解决办法
2103
查看次数