使用位操作会影响内存消耗?

Using bit operations influences memory consumption?

本文关键字:内存 影响 位操作      更新时间:2023-10-16

我正在做一个生物信息学的大学项目,遇到了一个非常奇怪的情况,我只是不明白。

为了优化计算生物序列中子序列哈希值的函数的CPU性能,我替换了以下内容:

hashValue += powf(4.0, k-i-1) * PHI_function((*seqence)[startIndex + i]);
//top of file has #include<cmath>

跟:

hashValue +=  (0x1 << (2*(k-i-1))) * PHI_function((*seqence)[startIndex + i]);
//top of file does not have #include<cmath> since powf is not used

变量解释:

//k is the sub-sequence length
//i is a index going from 0 to k
//sequence -> pointer to bio-sequence string 
//hashValue is of type int
//
//PHI_function has the following signature: inline int HashTableCalculationMethod::PHI_function(char b)
// and only conatins: return (b & 0x6) >> 1; 
//which means
// if (b == 'A') {
//     return 0;
// } else if (b == 'C') {
//     return 1;
// } else if (b == 'G') {
//     return 2;
// } else if (b == 'T') {
//     return 3;
// }

这将程序时间性能提高了 ~5 倍,但由于某种原因,内存消耗也从 ~4GB 增加到 ~7.5GB(在我收到的项目样本上运行时)。

我确信这是由于 Git 版本跟踪而影响内存消耗的更改(我在修改前后都有提交)。

有人可以解释一下这如何影响程序内存消耗吗?

项目可在链接中找到。更改性能的提交是 d39d055

提前谢谢你。

我真的只能看到两个选项。

显然,您的代码仍然像以前一样做 - 无论您如何计算,4k-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].您可以使用具有合理有限有效域的任何函数调用来执行此操作。在这里,我想你不能超过,什么,七十个值?

如果不是这样,您可能会在之前的提交中弄错,即最小化器向量在调用之间变得通用的提交。我无法遵循代码,但这是否会导致单个向量变得比应有的大 - 有点反向乔丹表示?你不会在单元测试中注意到它,这可能会让你相信更改没有任何变化 - 直到你在更大的集合上运行代码。