我正在进行生物信息学的大学项目,并且遇到了一个我不理解的非常奇怪的情况。
为了优化计算生物序列中子序列的哈希值的函数的CPU性能,我更换了以下内容:
repositoryCount
with:
query{
search(query:"name:*", type:REPOSITORY, first:50){
repositoryCount
pageInfo{
endCursor
startCursor
}
edges{
node{
... on Repository{
name
}
}
}
}
}
变量说明:
hashValue += powf(4.0, k-i-1) * PHI_function((*seqence)[startIndex + i]);
//top of file has #include<cmath>
这将程序时间性能提高了约5倍,但由于某种原因,内存消耗也从~4GB增加到~7.5GB(当我为项目收到的样本运行时)。
我确信这是因Git版本跟踪而影响内存消耗的变化(我在修改之前和之后都提交了)。
有人可以解释这是如何影响程序内存消耗的吗?
项目位于link。改变性能的提交是d39d055
提前谢谢你。
答案 0 :(得分:1)
我真的只能看到两种选择。
显然,你的代码仍然和以前一样 - 无论你如何计算,4 k-i-1 总是相同的数字。或者是吗?新计算产生一个整数,并将它乘以Phi。是否有可能导致Phi值被转换为整数以用于乘法目的? (似乎不太可能,但尝试将(1<<...)
转换为加倍才能看到)。如果该值未被解释为相同,那么这可能会影响哈希表中的冲突数,从而影响内存。
由于数据类型的限制,以上内容的变体是(1 << (2*(k-i-1)))
与powf()
的范围不同;你应该根据k检查最大可能值。情况应该是k-i-1
始终为正或零,并且总是低于31(或者是30?),或者63取决于整数大小。
然而,您可以预先计算 powf。这为您提供了两全其美的选择:快速计算和肯定正确的结果。如果索引始终为正,则在初始化之前运行
// vector of doubles. All copacetic as long as
// maxValue... is correctly estimated. Otherwise,
// "hello, undefined behaviour".
for (x = 0; x <= maxValueForKMinusIMinusOne; x++) {
powfTable[x] = powf(4.0, x);
}
在内核计算中,您将powf(4.0, k - i - 1)
替换为powfTable[k-i-1]
。 您可以使用合理限制的有效域进行任何功能调用。在这里,我想你不能拥有超过,有什么,七十个价值观?
如果不是这样,你可能会在之前的提交中被误认为是最小化向量在调用之间变得普遍的提交。我无法遵循代码,但是可能会这个结果导致单个向量增长得比它应该大 - 反向Jordan表示的类型?你不会在单元测试中注意到它,而可能会让你相信更改没有改变 - 直到你在更大的集合上运行代码。