我写了一个元胞自动机程序,将数据存储在矩阵(数组)中。对于300*200矩阵,我可以使用静态存储器分配(例如std::array
)实现每秒60次或更多次迭代。
我想在不每次重新编译程序的情况下生成不同大小的矩阵,即用户输入一个大小,然后开始模拟该矩阵大小。然而,如果我使用动态内存分配(例如std::vector
),模拟将降至每秒约2次迭代。我该如何解决这个问题?我采用的一种选择是预先分配一个比我预计用户将选择的更大的静态数组(例如2000*2000),但这似乎很浪费,并且在一定程度上仍然限制了用户的选择。
我想知道我是否可以
a) 分配内存一次,然后以某种方式"冻结"它以获得普通的静态阵列性能?
b) 或者在CCD_ 3上执行更高效的操作?作为参考,我只对矩阵执行matrix[x][y] == 1
和matrix[x][y] = 1
运算。
根据这个问题/答案,std::vector
和使用指针在性能上没有区别。
编辑:
根据UmNyobe的建议,我已经将矩阵重写为单个数组,通过matrix[y*size_x + x]
访问。使用动态内存分配(在启动时调整一次大小),我将性能提高了一倍,达到每秒5次迭代。
根据PaulMcKenzie的评论,我编译了一个发布版本,并获得了我想要的性能(每秒60次或更多迭代)。然而,这是更多的基础,所以我仍然想更彻底地量化一种方法相对于另一种方法的好处,所以我使用std::chrono::high_resolution_clock
对每次迭代进行计时,发现动态和静态阵列之间的性能差异(在使用单个阵列矩阵表示后)在误差范围内(每次迭代450~600微秒)。
不过,调试期间的性能有点令人担忧,所以我想我会保留两者,并在调试时切换到静态数组。
仅供参考,我只执行
matrix[x][y]
- 红旗矩阵是否使用
vector<vector<int>>
代理?这是一个错误,因为矩阵中的行会很远在记忆中分开。您应该使用大小为rows x cols
的单个矢量并使用matrix[y * row + x]
- 此外,您应该遵循先按行然后按列进行索引的方法,即
matrix[y][x]
而不是matrix[x][y]
。您的算法也应该以相同的方式进行处理。这是由于对于matrix[y][x]
(x,y)和(x+1,y)彼此是一个存储器块,而对于任何其它机制元件(x,y)
和(x + 1, y)
,(x, y + 1)
相距远得多
即使从std::array到std::vector的性能有所下降(因为数组可以在堆栈上有元素,这样更快),使用两个集合也可以在相同的幅度上执行一个不错的算法。