OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7463|回复: 9

求以下程序 运算速度最快的算法

[复制链接]

233

主题

961

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1817
金钱
1817
注册时间
2011-10-9
在线时间
231 小时
发表于 2013-1-7 16:00:46 | 显示全部楼层 |阅读模式

#define HEAD1_D3 PFout(6)

u8 x; 
-----以上是声明--------

HEAD1_D3=x&0x01; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;  //先送最低位
HEAD1_D3=(x&0x02)>>1; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;  
HEAD1_D3=(x&0x04)>>2; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
HEAD1_D3=(x&0x08)>>3; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
HEAD1_D3=(x&0x10)>>4; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
HEAD1_D3=(x&0x20)>>5; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
HEAD1_D3=(x&0x40)>>6; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
HEAD1_D3=(x&0x80)>>7; HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

233

主题

961

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1817
金钱
1817
注册时间
2011-10-9
在线时间
231 小时
 楼主| 发表于 2013-1-7 16:11:23 | 显示全部楼层
还有1个写法 但是速度差不多


for (i=0;i<8;i++)
{
    HEAD1_D3=x&0x01;  HEAD1_DTSB_CLR;HEAD1_DTSB_SET;
   x=x>>1;


}
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2013-1-7 16:52:26 | 显示全部楼层
写 256 个函数, 建立一个函数指针表, 用 x 作为索引查表试试
https://github.com/roxma
回复 支持 反对

使用道具 举报

20

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
334
金钱
334
注册时间
2012-8-21
在线时间
27 小时
发表于 2013-1-7 17:48:25 | 显示全部楼层
LS的说法是可以的,做个指针表,要么就用宏加快速度,不推荐使用循环,
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2013-1-7 18:00:34 | 显示全部楼层
用gcc在 Os 选项下编译了, 然后用 mdk 软件仿真简单测试了下, 用了个大循环, 总共用时从原来的 0.071s 降到了 0.066s, 不过代码从原来的不到 1k 变成了 18k, 

如果速度真的那么重要的话 ... ... 

以下是部分测试代码供楼主参考, 想自己测试的话需要自己修改部分内容.

extern void (* const fun[])();
void fun2(u8);

int main(){

int i = gpioa; // 禁止编译器优化

for(; i<0xffff; i++)
fun[i&0xff]();
//fun2(i);
while(1);
}

PinRename(pa1,HEAD1_D3);
PinRename(pa2,HEAD1_DTSB);

void fun2(u8 x){
HEAD1_D3=x&0x01;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x02)>>1; HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x04)>>2;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x08)>>3;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x10)>>4;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x20)>>5;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x40)>>6;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
HEAD1_D3=(x&0x80)>>7;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set();
}

#define fun_impl(hex1,hex2) \
void fun_##hex1##hex2(){ \
constexpr int x = hex1<<8|hex2; \
HEAD1_D3=x&0x01;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x02)>>1; HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x04)>>2;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x08)>>3;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x10)>>4;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x20)>>5;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x40)>>6;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
HEAD1_D3=(x&0x80)>>7;  HEAD1_DTSB.Reset();HEAD1_DTSB.Set(); \
}

#define fun_impl_group(hex) \
fun_impl(hex, 0x0) \
fun_impl(hex, 0x1) \
fun_impl(hex, 0x2) \
fun_impl(hex, 0x3) \
fun_impl(hex, 0x4) \
fun_impl(hex, 0x5) \
fun_impl(hex, 0x6) \
fun_impl(hex, 0x7) \
fun_impl(hex, 0x8) \
fun_impl(hex, 0x9) \
fun_impl(hex, 0xa) \
fun_impl(hex, 0xb) \
fun_impl(hex, 0xc) \
fun_impl(hex, 0xd) \
fun_impl(hex, 0xe) \
fun_impl(hex, 0xf)

fun_impl_group(0x0)
fun_impl_group(0x1)
fun_impl_group(0x2)
fun_impl_group(0x3)
fun_impl_group(0x4)
fun_impl_group(0x5)
fun_impl_group(0x6)
fun_impl_group(0x7)
fun_impl_group(0x8)
fun_impl_group(0x9)
fun_impl_group(0xa)
fun_impl_group(0xb)
fun_impl_group(0xc)
fun_impl_group(0xd)
fun_impl_group(0xe)
fun_impl_group(0xf)

#define fun_addr(hex1,hex2) &fun_##hex1##hex2

#define fun_addr_group(hex) \
fun_addr(hex,0x0) , \
fun_addr(hex,0x1) , \
fun_addr(hex,0x2) , \
fun_addr(hex,0x3) , \
fun_addr(hex,0x4) , \
fun_addr(hex,0x5) , \
fun_addr(hex,0x6) , \
fun_addr(hex,0x7) , \
fun_addr(hex,0x8) , \
fun_addr(hex,0x9) , \
fun_addr(hex,0xa) , \
fun_addr(hex,0xb) , \
fun_addr(hex,0xc) , \
fun_addr(hex,0xd) , \
fun_addr(hex,0xe) , \
fun_addr(hex,0xf)

void (*const fun[])() = 
{
  fun_addr_group(0x0)
, fun_addr_group(0x1)
, fun_addr_group(0x2)
, fun_addr_group(0x3)
, fun_addr_group(0x4)
, fun_addr_group(0x5)
, fun_addr_group(0x6)
, fun_addr_group(0x7)
, fun_addr_group(0x8)
, fun_addr_group(0x9)
, fun_addr_group(0xa)
, fun_addr_group(0xb)
, fun_addr_group(0xc)
, fun_addr_group(0xd)
, fun_addr_group(0xe)
, fun_addr_group(0xf)
};
https://github.com/roxma
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2013-1-7 18:03:57 | 显示全部楼层
使用循环, 只要循环次数不大并且能在编译期确定, 在为速度优化的时候编译器也可能把循环体展开的,
所以楼主提供的两种代码在让编译器优化(不管是选择为速度还是为大小), 都有可能生成一模一样的汇编代码, 具体情况就要看编译器的能力了.
https://github.com/roxma
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2013-1-7 18:15:56 | 显示全部楼层
回复【5楼】Pony279:
---------------------------------

补充一下, 如果把查表法函数里面的HEAD1_D3操作都改成使用 BSR 和 BSRR 寄存器而不是位带操作, 大循环的时间可以缩小到 0.060 s
https://github.com/roxma
回复 支持 反对

使用道具 举报

233

主题

961

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1817
金钱
1817
注册时间
2011-10-9
在线时间
231 小时
 楼主| 发表于 2013-1-8 10:59:32 | 显示全部楼层
额  实在太给力了  按照这个方法修改了下程序 速度提高了 15%左右    呵    谢谢啊~~ 
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2013-1-8 14:03:31 | 显示全部楼层
回复【8楼】simms01:
---------------------------------

查表法还有优化空间的, 因为相邻两个位为同样的数字的时候不需要重复写数据口, 

不过这种方式太占代码空间了, 没必要, 20 k 的 flash 的 $ 应该可以用来买好几个硬件实现的了...
https://github.com/roxma
回复 支持 反对

使用道具 举报

27

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2012-8-11
在线时间
0 小时
发表于 2013-1-8 22:36:06 | 显示全部楼层
回复【9楼】Pony279:
---------------------------------
好厉害~~学习了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-21 11:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表