求助:程序速度比较
数组 a~a,共n个元素。
组成数值圆环,首尾相连。
首值下标 i=0,向后移动(i++)
尾值下标 j=n-1,向前移动(j--)
如何做到数值循环访问,以下有2个方案
方案A:
while (true)
{
if( i≠(n-1) )
i++ ;
else
i=0 ;
if( j≠0 )
j-- ;
else
j=n-1 ;
其它程序段
}
方案B:
while (true)
{
i = (i+1)modn;
j = (n+j-1)modn;
其它程序段
}
两种边界处理方式,哪个更快一些?
例如采用C++编译,方案A 的 if 语句,方案B 的mod运算,耗用机器指令的时钟周期,相差有多少?
个人有以下理解,if 语句 编译成机器语言后,大约耗时20个时钟。而mod运算本质上是除法指令,大约耗时200个时钟。两者耗时相差10倍。
这样理解是否有误区?
个人更喜欢方案A,直观、简单、容易理解。
而方案B,看起来高大上,纸面上程序简洁,但是难理解,而且速度慢。
这种东西问AI 比上S1问又快又准,合理怀疑楼主就是想要白嫖ai回答,这是claude 答案:
结论先说:你的方向对(方案A通常更快),但两个数字都不准,各错了一个数量级。
**if 语句的真实开销**
编译后是 `cmp` + 条件跳转,在现代 x86 上这俩经常宏融合成一条 µop。关键在分支预测:
- 预测命中:约 1~2 个周期,几乎免费
- 预测失败:才是你说的 15~20 周期(流水线清空)
而你这个分支极其规律——n 次循环里只有 1 次走 else 分支,预测器轻松学会,几乎每次都命中。所以方案A的真实成本接近 1~2 周期,不是 20。
**mod 的真实开销**
mod 编译成 `div`/`idiv` 指令。32 位除法在 Skylake 上延迟约 20~26 周期,Ice Lake / Zen 3 之后已优化到约 10~18 周期,64 位会更慢一些。不是 200,200 周期那是上世纪的 CPU 或软件模拟除法的水平。
所以真实差距大约还是 10 倍量级(2 周期 vs 20 周期),你的结论碰巧成立,但绝对值都高估了 10 倍。
**三个重要的"但是"**
1. 如果 n 是编译期常量,编译器根本不会生成 div,而是用乘法+移位的魔数技巧(约 4~6 周期);如果 n 是 2 的幂,直接 `and` 掩码,1 个周期,这时方案B反而最快。
2. 比你的方案A更优的写法是:
```cpp
if (++i == n) i = 0;
if (j-- == 0) j = n - 1;
```
逻辑等价但编译器很容易把它生成 `cmov`(条件传送),完全无分支、无预测失败风险,稳定 2~3 周期。这是环形缓冲区的标准写法。
3. 实战中这点差距通常无关紧要——循环体里只要碰一次内存(数组访问、cache miss 几十到几百周期),索引回绕的开销就被淹没了。除非循环体极小且全在寄存器里跑,否则 A/B 测不出差别。
所以你的审美没问题:方案A(或上面的 cmov 友好写法)直观且快。方案B 的价值主要在 n 为 2 的幂时(掩码写法 `i = (i+1) & (n-1)` 既简洁又是最快的),通用变量 n 下确实是又慢又"装"。
let mut forward = (0..n).cycle();
let mut backward = (0..n).rev().cycle();
loop {
let i = forward.next().unwrap();
let j = backward.next().unwrap();
}
Rust,别纠结这个了,编译器比你想象中的聪明 看了看楼主发帖记录 楼主这是把探油当AI用了 也是提前好几年用上“人工”智能了 Xerxes_2 发表于 2026-6-12 15:02
Rust,别纠结这个了,编译器比你想象中的聪明
看不懂,话说这是什么语言?
还是C++的某种库模版?(之前我猜测,已经有某种现成的环状数据结构,提供给设计者使用)
proof1 发表于 2026-6-12 18:09
看不懂,话说这是什么语言?
还是C++的某种库模版?(之前我猜测,已经有某种现成的环状数据结构,提供 ...
Rust,我说了啊 楼主先评估下是否真到了需要抠这点性能的地步
—— 来自 Xiaomi 22041211AC, Android 12, 鹅球 v4.0.100-alpha 楼主是程序员吗?我不是程序员都知道rust 子犴 发表于 2026-6-12 15:53
看了看楼主发帖记录 楼主这是把探油当AI用了 也是提前好几年用上“人工”智能了 ...
“人肉搜索”这个词已经变死语了吗 为什么知名活化石proof1**还在纠结编程问题?本来以为到了AI时代**应该已经没有上泥潭的必要了
我甚至记得去年还是前年他问过一个vf6.0的问题 我雷达响了,是 python 侠! ring buffer直接用boost库里的不就行了,干嘛手搓啊
—— 来自 Xiaomi 24129PN74C, Android 16, 鹅球 v3.5.99 没有benchmark的性能讨论毫无意义
—— 来自 Xiaomi 23049RAD8C, Android 15, 鹅球 v3.5.99 本帖最后由 proof1 于 2026-6-13 21:57 编辑
2. 比你的方案A更优的写法是:
if(++i == n) i = 0 ;
if(j-- == 0) j = n-1 ;
这是环形缓冲区的标准写法。
if(j-- == 0) j = n-1 ;
不解
A、先判断,如果j≠0,执行j--,略过 j=n-1
B、先判断,如果j=0,执行j--,执行 j=n-1
是这个过程吗?
袄_偶滴小乔 发表于 2026-6-12 20:43
“人肉搜索”这个词已经变死语了吗
过去只有这个词 但是现在回头看 “搜索”已经不足以形容楼主这种行为了 这不是单纯从已有资料中查找 而是让探油无私创造 😄 袄_偶滴小乔 发表于 2026-6-12 20:43
“人肉搜索”这个词已经变死语了吗
人肉搜索是死语了没错
但是死语的原因是这个词的词义放今天叫“开盒”啊 盐星 发表于 2026-6-14 00:36
人肉搜索是死语了没错
但是死语的原因是这个词的词义放今天叫“开盒”啊 ...
开盒是指人肉搜索的对象是人,媒体传多了把最关键的因素给传没了,导致这个词后期有所转义。“人肉“是和”搜索引擎“相对的,那个时期最典型的人肉搜索其实是百度知道 鹅球4.0进来就看见负鹅,很方便 h哈哈,lz全是求助贴, 一排
页:
[1]