能否用C语言其他语句实现switch语句的功能,并且性能不比switch更低?

iwillalwaysloveyou 2012-06-15 08:05:16
我用的一个编译器,由于跳转表每项是3字节,在计算跳转的时候,使用了乘法,大大降低了性能,

我的程序大致如下:

switch(x)
{
case 0:
do_some_thing();
break;
case 1:
do_some_thing();
break;
case 2: do_some_thing();
break;
...

case 120:
do_some_thing();
break;
default:
...
break;
}

不要使用函数表(虽然避免了乘法但是函数调用开销也不小)


...全文
282 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Binzo 2012-06-16
  • 打赏
  • 举报
回复
要快你也要硬件支持啊,不然大家都用51跑Win7了。
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
见9楼

[Quote=引用 14 楼 的回复:]

先用函数指针简化代码,然后那个跳转表有改成4字节的可能行么
[/Quote]
天台的故事 2012-06-15
  • 打赏
  • 举报
回复
先用函数指针简化代码,然后那个跳转表有改成4字节的可能行么
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
跳转表几个字节是由编译器控制的,我控制不了
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
空间优化不一定能提升性能,
我试过关掉合并尾部代码优化,空间增大但性能有提升,
这个核缓存太少了只有1k
在考虑试试手动配置缓存
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
你的cpu移位运算几个周期?应该比乘法快吧
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
跟跳转表几个字节没关系,4个字节编译器产生的就是mov b, 4, mul a,b了,这个编译器很懒
[/Quote]

你是要乘3是吧,你就手动优化试试

X*3 = X*(2+1)= X*2 + X = X<<1 + X

一个移位一个加法

乘4更简单

X*4 = X<<2

一个一位搞定

另外我给你的函数指针优化主要是空间上的,在指令周期差不多,但程序占用空间减少的情况下,至少intel CPU的缓存命中率会提高,速度会更快,51不清楚,反正函数指针没坏处
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
跟跳转表几个字节没关系,4个字节编译器产生的就是mov b, 4, mul a,b了,这个编译器很懒
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
我计算了一下,改成函数指针时间差不多:

在我用的cpu上,
取函数地址,至少6,
ECALL 6
ERET 7

乘法MUL AB的时间是19

最快的是用两次加法指令,加上一个mov指令3个周期,但编译器不这么干
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
先用函数指针简化代码,然后那个跳转表有改成4字节的可能行么
iwillalwaysloveyou 2012-06-15
  • 打赏
  • 举报
回复
没错,是用51,并且switch case要非常频繁地调用
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
引用 3 楼 的回复:

你说的乘法是说x用乘法计算出来的么?如果x只计算一次,这个还叫开销?x86这种CISC的乘法器直接硬件支持,没多慢

我越发觉得lz在用51……
[/Quote]

那就先用函数指针数组优化吧,120个case一行就搞定了,最多之前判断一下x的上下限
xunxun 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

你说的乘法是说x用乘法计算出来的么?如果x只计算一次,这个还叫开销?x86这种CISC的乘法器直接硬件支持,没多慢
[/Quote]
我越发觉得lz在用51……
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
你说的乘法是说x用乘法计算出来的么?如果x只计算一次,这个还叫开销?x86这种CISC的乘法器直接硬件支持,没多慢
jackyjkchen 2012-06-15
  • 打赏
  • 举报
回复
函数表为什么“调用开销也不小”

我理解函数表不就是个“函数指针数组”,pFunc[]

你所有的do_something的地址都是一个成员

然后直接pFunc[x]就直接能调相应的函数了

你这种非常规律的从0开始索引且一直连续的最适合用函数指针数组了,比switch好,时间空间都好
beckhanyan 2012-06-15
  • 打赏
  • 举报
回复
我表示没听说过函数表是啥

typedef (*VoidFunc)();
//表驱动,定义表
VoidFunc _FuncTable[] = {
do_some_thing,
do_some_thing,
do_some_thing
};
//使用
if(x < _countof(_FuncTable))
_FuncTable[x]();

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧