![]() |
1
7
这确实需要分析,但您可能需要考虑另一种选择:
通常位移动和位操作比乘法快,然而,if语句可能比乘法慢,尽管使用分支预测和大L,我猜它可能更快。不过,你真的需要对它进行分析,以确定它是否会导致加速。 正如下面的注释中指出的,手动或通过编译器标志(如GCC上的“-funcroll loops”)展开循环也可以加快速度(消除循环条件)。
编辑
|
![]() |
2
4
研究SSE2的建议有用吗?它已经有了点产品类型的操作,另外你可以做4次(或者8次,我忘记了寄存器的大小)简单的并行迭代。 SSE还具有一些简单的逻辑类型操作,因此它可以在不使用任何条件操作的情况下进行加法而不是乘法…你得再看看有什么行动。 |
![]() |
3
4
试试这个:
这将避免使用条件语句,并使用位运算符来用零或一屏蔽标量值。 |
![]() |
4
3
因为尺寸明确 不存在 重要的是,我认为以下可能是最有效的通用代码:
位编码
当然,正如其他人所指出的,循环展开可以极大地加快速度。 |
![]() |
5
2
此解决方案与Micheal Aaron的相同,但速度稍快(根据我的测试):
我认为有一种数字方法可以快速建立一个字中的下一个集合位,如果你的X数据非常稀疏,但目前找不到所说的数字公式,这将提高性能。 |
![]() |
6
2
我已经看到了一些有点诡计的响应(为了避免分支),但没有一个正确的循环imho:。/
优化
优势:
现在,我想知道它是否运行得更快,特别是因为for循环的过早停止可能不像展开循环那样容易(与编译时常量相比)。 |
![]() |
7
2
把一个移位循环和一个小的查找表结合起来怎么样?
这将取决于编译器对switch语句的优化程度,但根据我的经验,他们现在非常擅长于此…… |
![]() |
8
1
这个问题可能没有一般性的答案。您需要在所有不同的目标下分析您的代码。性能将取决于编译器优化,如循环展开和SIMD指令,这些指令在大多数现代CPU上都可用(x86、PPC、ARM都有自己的实现)。 |
![]() |
9
1
为了 小的 l,可以使用switch语句而不是循环。例如,如果L=8,则可以有:
如果l=32,可以编写一个dot32()函数,调用dot8()。 四 时间,如果可能,内联。(如果编译器拒绝内联dot8(),可以将dot8()重写为宏以强制内联。) 补充 :
正如Mikera指出的,这个解决方案可能有一个指令缓存成本;如果有,使用 DOT4 ()函数可能有帮助。 进一步更新 :这可以与Mikera的解决方案相结合:
使用-s-o3选项查看生成的汇编程序代码 海湾合作委员会 4.3.4在cygwin上,看到它在dot32()中自动内联,我有点惊讶,因为 八 16个入口跳台。 但是添加属性(noinline)似乎可以产生更好的汇编程序。 另一种变化是在switch语句中使用fall through,但是 海湾合作委员会 添加了JMP指令,它看起来不会更快。 编辑--全新答案: 在考虑了蚂蚁AASMA提到的100次循环惩罚以及其他答案之后,上述问题可能不是最佳的。相反,你可以 手动 展开循环,如下所示:
在我的机器上,它生成32 x 5=160个快速指令。一个聪明的编译器可以想当然地展开其他建议的答案,得到相同的结果。 但我还是在复查。 |
![]() |
10
1
|
![]() |
11
1
很可能是加载所花费的时间
另一个相关的问题是编译器是否会为
(康拉德·鲁道夫在评论中质疑这一点,对记忆感到疑惑 使用 . 这不是现代计算机体系结构中真正的瓶颈,内存和CPU之间的带宽是。如果y已经在缓存中,那么这个答案几乎是不相关的。) |
![]() |
12
0
您可以将位向量存储为一个int序列,其中每个int将几个系数打包为位。然后,分量相乘等于位和。有了这个,您只需要计算可以这样做的设置位数:
要想计算设定位,请参见 http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 编辑:抱歉,我刚刚意识到只有一个向量包含0,1的元素,而另一个不包含0,1的元素。这个答案只适用于两个向量都限于0,1集的系数的情况。 |
![]() |
13
0
代表
|
![]() |
14
0
如果它是1,你希望所有的位都过去;如果它是0,你希望所有的位都过去。所以你想以某种方式把1变成-1(即0xffffffff),0保持不变。那只是-x……所以你…
对于每个元素…工作完成了吗? edit2:要给出一个代码示例,您可以这样做并避免使用分支:
当然,最好是将1和0保持在整数数组中,从而避免移位。 编辑:值得注意的是,如果y中的值的大小为16位,那么您可以执行其中的2个操作和每个操作(如果您有64位寄存器,则为4个)。但是,它确实意味着将x值1乘以1求反为一个更大的整数。 ie yvals=-4,3 in 16位=0xfffc,0x3…放入1个32位,得到0xfffc0003。如果你有1,0作为x值,那么你就形成了一个0xffff0000的位掩码,2加在一起,你得到了2个1位和op的结果。 另一个编辑: 如果你想要关于如何做第二种方法的代码 喜欢 这应该可以工作(尽管它利用了未指定的行为,因此可能无法在每个编译器上工作)。在我遇到的每个编译器上工作)。
希望编译器会优化分配(我不确定,但这个想法可以重新实现,所以它们肯定是),并给你一个小的速度,因为你现在只需要做1位,而不是2位。但是速度会很小… |
![]() |
Muhammad Umer · 为什么这个随机数猜谜游戏模拟产生5.8 5 月前 |
![]() |
Alisa Petrova · 在有向图中更改一对顶点以创建循环 6 月前 |
|
D W · Python-将浮点数从2转换为10到100位小数 7 月前 |
![]() |
Bartol · 确定python龟图形中的角度 11 月前 |
|
randomAlgo · 将弹簧设置为相同长度的成本最低 11 月前 |
![]() |
Fyodor · 在C中使用sin和cos计算数学表达式不正确? 1 年前 |
![]() |
Sergio · python中大量数字的乘法 1 年前 |