我想写一个函数,返回最近的2个数的下一个幂.例如,如果我的输入是789,输出应该是1024.有没有任何方法可以实现这一点而不使用任何循环但只使用一些按位运算符?
我正在寻找一种有效的方法来确定在整数中设置的最低有效位的位置,例如对于0x0FF0,它将是4.
这是一个简单的实现:
unsigned GetLowestBitPos(unsigned value)
{
assert(value != 0); // handled separately
unsigned pos = 0;
while (!(value & 1))
{
value >>= 1;
++pos;
}
return pos;
}
Run Code Online (Sandbox Code Playgroud)
任何想法如何挤出一些周期?
(注意:这个问题适合喜欢这类事情的人,而不是人们告诉我xyzoptimization是邪恶的.)
[编辑] 感谢大家的想法!我也学到了其他一些东西.凉!
如果我有一个整数n,我怎样才能找到的下一个号码k > n,使得k = 2^i,其中一些i的元件N由按位移动或逻辑.
示例:如果我有n = 123,我怎么能找到k = 128,哪个是2的幂,而不是124哪个只能被2整除.这应该很简单,但它让我望而却步.
在测量某些东西的同时,我测量的吞吐量比我计算的要低得多,我将其缩小到LZCNT指令(它也发生在TZCNT中),如以下基准所示:
xor ecx, ecx
_benchloop:
lzcnt eax, edx
add ecx, 1
jnz _benchloop
Run Code Online (Sandbox Code Playgroud)
和:
xor ecx, ecx
_benchloop:
xor eax, eax ; this shouldn't help, but it does
lzcnt eax, edx
add ecx, 1
jnz _benchloop
Run Code Online (Sandbox Code Playgroud)
第二个版本要快得多.它不应该.LZCNT没有理由对其输出有输入依赖性.与BSR/BSF不同,xZCNT指令总是覆盖其输出.
我在4770K上运行它,所以LZCNT和TZCNT没有被执行为BSR/BSF.
这里发生了什么?
有很多关于如何找到给定值的2的下一个幂的信息(参见参考文献),但我找不到任何以前的2的幂.
到目前为止,我找到的唯一方法是保持一个具有2的所有幂的表,最多2 ^ 64并进行简单的查找.
我正在用C#进行流体模拟.每个循环我需要计算空间中离散点处流体的速度.作为计算的一部分,我需要几十千字节的空间来容纳一些double []数组(数组的确切大小取决于一些输入数据).数组仅在使用它们的方法的持续时间内需要,并且有一些不同的方法需要这样的临时空间.
在我看来,有一些不同的解决方案来构建临时数组:
每次调用方法时,使用'new'从堆中获取内存.这就是我最初做的事情,但是它给垃圾收集器带来了很大的压力,而每秒一到两次的几毫秒尖峰真的很烦人.
在调用方法时将临时数组作为参数传递.问题是,这迫使用户管理它们,包括适当地调整它们,这是一个巨大的痛苦.并且它使得使用或多或少的临时存储器变得困难,因为它改变了API.
在不安全的上下文中使用stackalloc从程序堆栈中分配临时内存.这可以正常工作,除了我需要使用/ unsafe进行编译并在我的代码中不断地散布不安全的块,我想避免.
程序启动时预先分配私有数组.这很好,除非我不一定知道我需要的数组的大小,直到我可以查看一些输入数据.它变得非常混乱,因为你不能将这些私有变量的范围限制为单一方法,因此它们不断地污染命名空间.并且随着需要暂存内存的方法数量的增加,它的扩展性很差,因为我分配的内存很多,只占用了一小部分时间.
创建某种中央池,并从池中分配临时内存阵列.这个问题的主要问题是我没有看到从中央池分配动态大小的数组的简单方法.我可以使用起始偏移和长度,并且所有临时内存基本上共享一个大型数组,但我有很多现有的代码假定double [] s.而且我必须小心使这样的池线程安全.
...
有没有人有类似问题的经验?从经验中提供的任何建议/课程?
我刚刚读到了关于铸造返回值的不良做法malloc.如果我理解正确的话,离开演员是绝对合法的,因为它是隐含的(并且应该留下,因为它可能产生其他问题).那么我的问题是,我什么时候应该施展我的价值观呢?有一些一般规则或什么?例如,此代码编译时没有任何错误gcc -W -Wall(除了未使用bar,但这不是重点):
float foo(void) {
double bar = 4.2;
return bar;
}
int main(void) {
double bar = foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我现在很困惑.有关铸造的良好做法和规则是什么?
谢谢.