我的应用程序将在密集矩阵上执行大量矩阵运算(例如,加/乘)。我想缓存唯一的结果,以避免重复计算。
密集矩阵:
typdef struct denseMatrix{
int m;
int n;
double **d; // actual matrix
multiplyTable **entry; // key & result
} dns;
表条目:
typedef struct multiplyTable{
dns *rightOperand; // key
dns *result; // value
} multiplyTable; // or something like that
dns *A, *B, *C, *D...; // allocated internally
C = mult(A,B); //may be called many many times.
在这种情况下,mult会向表中添加一个条目(操作数,结果)对
add(A->entry, B, C); //B is the right operand and C is the result
稍后如果再次调用D = mult(A,B),则搜索(A->条目,B)将检索C.如果另一方面,特定操作数不在列表中,则会与指向结果矩阵的指针一起添加。
我之前从未做过这样的事情,我甚至不确定这是否是解决问题的方法。根据我的有限理解,哈希表可用于实现类似的东西。
我的实际问题包括: (a)哈希表首先是问题的合适解决方案吗?它们是否允许指针地址作为键和值
(b)将“哈希表”保留为结构中的“字段”是否有意义?这样,我已经有了左操作数,我只需要在乘法表中搜索rightOperand。或者,是否应该有一个左右操作数都作为键的独立表?
(c)我是否为加法/乘法等创建单独的表,或者是否应该有一个表,包含操作数和运算符?
(d)什么是跟踪所有创建的对象以便可以正确释放的最好方法?
(e)什么公开的图书馆(c)适合实施这样的东西?
我正在寻求有关(a)可以解决问题的替代方法的投入/建议,以及(b)此类替代方案的优点/缺点。
最后,我发现这个论坛非常有用,我想表达我的感激之情。 ++感谢。
答案 0 :(得分:1)
你必须非常小心哈希。如果您有碰撞(不同原始值的哈希值相同),您可能会得到错误的结果。 你确定计算矩阵的散列比执行实际操作更有效(这一切都取决于这些操作的数量/复杂性)
第二个问题 - 你没有说过你的缓存驱逐政策。您是否只是添加到哈希表而不删除?根据不同矩阵的数量,您可能会耗尽内存......
答案 1 :(得分:0)
首先回答简单部分:对于矩阵运算的C ++库,请查看newmat,它内置了大量功能,并且性能非常高效。
对于构建哈希以加速计算的特定情况 - 除非您要在非常有限的矩阵集上执行操作,否则缓存是值得的。要为矩阵构建唯一的哈希,您需要访问每个条目 - 并根据每个条目的位置和值计算哈希值。更糟糕的是,矩阵并不总是可交换的,例如, A B!= B A,特殊情况除外。
这意味着您的缓存必须为每个特定计算存储一个条目。因此,除非您处理的是非常小范围的输入矩阵,否则保存所有结果的内存成本将非常高。
缓存会加速结果,但只能在非常有限的情况下使用。
鉴于您已经征求了关于库的建议,这听起来像是过早优化的情况。我将实现您的程序而不进行缓存,性能配置文件,如果您在阵列算术中发现性能瓶颈,然后考虑优化数字运算的方法。
编辑:计算哈希值:如果你有一个n×m矩阵X,那么计算那个矩阵的哈希值至少和操作R X C一样复杂,其中R是行向量[1,..,n],C是列向量[1,..,m]。我还没有计算出最优的收益,但对于2x2量级的非常小的矩阵,做原始计算的3x3将比计算哈希值便宜。
答案 2 :(得分:0)
此功能称为memoization - 有关详细信息,请参阅wikipedia文章。
本文还提到了一些可以帮助您的图书馆。