MegaHealth 发表于 2021-7-30 09:54:08

c51数组定义时初始化很耗时,大神帮忙解读一下

void test(void)
{
      uint8_t tmp = {0};

      tmp = 1;
}
这个测试代码对应汇编如图:
实测耗时:

void test1(void)
{
    uint8_t i;
    uint8_t tmp;

    for (i = 0; i < 100; i++)
    {
      tmp = 0;
    }
}

这个测试代码的汇编如图:

实测耗时如下:


结论:
    定义时初始化,耗时700多us是定义时不初始化,通过for循环初始化耗时(160us)的几倍。
    看汇编是因为定义时初始化,做了一系列的寄存器操作(看似无关),请大神指教一下,这个时候在干什么?

vtte 发表于 2021-7-30 10:10:22

C代码跟汇编代码看起来对不上,把优化关掉再看一下。

lb0857 发表于 2021-7-30 10:11:19

uint8_t tmp = {0};
void test(void)
{
      tmp = 1;
}

不同的ide软件会有不同的编译算法   一般是预编译的时候进行滴
如果很在意这160us   那么编程风格经验等等都需要慢慢去磨哦

keshipt 发表于 2021-7-30 10:12:41

如楼上所说,感觉和编译器设置有关,很明显你的第一个图片有PWM 和urat相关的指令,和你的C代码对不上

MegaHealth 发表于 2021-7-30 11:04:58



编译器关掉优化之后的汇编如图

MegaHealth 发表于 2021-7-30 11:06:46

keshipt 发表于 2021-7-30 10:12
如楼上所说,感觉和编译器设置有关,很明显你的第一个图片有PWM 和urat相关的指令,和你的C代码对不上 ...

我上传了关掉优化的汇编,您看一下,我感觉优化只对for循环起了效果。char buf = {0};这种方式,好像是初始化前先进行了现场保护,所以耗费了一些时间。

kinoko 发表于 2021-7-30 11:07:12

我也发现这个问题,c51的变量在定义时初始化耗时更多,但没深究。目前都是在临时变量使用前赋初值。

MegaHealth 发表于 2021-7-30 11:07:30

lb0857 发表于 2021-7-30 10:11
不同的ide软件会有不同的编译算法   一般是预编译的时候进行滴
如果很在意这160us   那么编程风格   ...

不想把buf放到外面去,这样它就一直占着内存了

初音之恋 发表于 2021-7-30 11:14:01

可以再对比下memset速度

lb0857 发表于 2021-7-30 11:32:06

MegaHealth 发表于 2021-7-30 11:07
不想把buf放到外面去,这样它就一直占着内存了

有时候砸门的想法和编译器有差异哦
buf不好到外面有时候 还不是占用内存
不同编译器不同环境有差异
真的很在乎高效   汇编是很好的选择
只可惜 这门编程技术慢慢失传啦等楼主发扬光大

lindabell 发表于 2021-7-30 11:36:46

51 data 才多少,你就要了100 Bytes

keshipt 发表于 2021-7-30 11:43:29

MegaHealth 发表于 2021-7-30 11:06
我上传了关掉优化的汇编,您看一下,我感觉优化只对for循环起了效果。char buf = {0};这种方式,好 ...

在这个测试代码之前有没有开其他中断?

MegaHealth 发表于 2021-7-30 13:17:13

keshipt 发表于 2021-7-30 11:43
在这个测试代码之前有没有开其他中断?

timer中断是常开的

MegaHealth 发表于 2021-7-30 13:18:44

lindabell 发表于 2021-7-30 11:36
51 data 才多少,你就要了100 Bytes

用了外部的

modbus 发表于 2021-7-30 13:51:56

第二个for循环并没有初始化数组

keshipt 发表于 2021-7-30 13:58:05

modbus 发表于 2021-7-30 13:51
第二个for循环并没有初始化数组

还真是,不注意看都没有发现,只初始化了 tmp = 0;{:sweat:}

MegaHealth 发表于 2021-7-30 14:31:40

modbus 发表于 2021-7-30 13:51
第二个for循环并没有初始化数组

大意了,所以优化的时候可能直接把for的循环优化掉了,不开优化之后两个时间接近

at90s 发表于 2021-7-30 15:47:07

uint8_t tmp = {0};
看汇编似乎是把rom里面连续100个0拷贝到tmp里面了,因为我看到LCALL C?COPY的函数调用。

而用for循环就是直接向tmp所在地址填0

孤独飞行 发表于 2021-8-6 11:26:49

.A51里面有初始化RAM的代码,汇编的。精简得很,加载就好了。

t3486784401 发表于 2021-8-6 11:37:26

看到 C?COPY 函数没,清理的寄存器是这个函数的参数
页: [1]
查看完整版本: c51数组定义时初始化很耗时,大神帮忙解读一下