编写STM32程序,uint8_t、uint16_t数据类型是否影响原子操作?
我从8位机的时代走过来,思维还是这样的:uint8_t够用,就不用uint16_t,uint16_t够用的,就不用uint32_t.但32位系统中,用uint8_t时,编译出来的汇编指令数增加了。但uint16_t好像跟uint32_t一样的指令数。
除了指令数,临界区原子操作也有影响。比如,我中断里面对int32_t类型的数据加1,中断外面对这个数据减1,单周期操作完成,可以不用临界区保护。如果用uint8_t,会有问题。
不知道上面对否?各位可否共同探讨一下? 要改变观念了,以后32位单片机越来越强,编程也越来越PC化,所以变量定义最好直接用32位或者16位,这样以后程序再怎么升级,基本不会有溢出问题 我也试过,同样的延时函数,将变量定义为16位数据比8位数据的执行起来更快 你声明一个变量的时候,51奇葩可能将它放在的了内部的128字节的寄存器,所有有在内部的128字节的寄存器有单条自增和自减。
但是在其他CPU上面,基本都是将他放在内存上,都是读,修改,写回。不管是什么类型,基本不会有单周期可以完成的 认同楼主的用法,当然优先按需求分配空间。 楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成 modbus 发表于 2015-6-25 10:30
楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成 ...
我要重新看看《Cortex M3权威指南》了。 如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。 modbus 发表于 2015-6-25 10:42
如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。 ...
请问:用16位与32位,效率上有多大区别?我没做更多的测试,只测试过少量的几个函数。我的测试结果是没有区别。 ruanxianwu 发表于 2015-6-25 10:16
你声明一个变量的时候,51奇葩可能将它放在的了内部的128字节的寄存器,所有有在内部的128字节的寄存器有单 ...
那样的话,uint8_t只影响执行效率,要原子操作,还是需要临界区保护措施。比如互斥体技术。你的意见呢? modbus 发表于 2015-6-25 10:42
如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。 ...
还请补充依据或出处? guolun 发表于 2015-6-25 10:50
那样的话,uint8_t只影响执行效率,要原子操作,还是需要临界区保护措施。比如互斥体技术。你的意见呢? ...
嗯,uint8_t不一定比uint32_t快的。跟机器处理位数匹配的是效率最高的,STM32是32位的,所以uint32_t至少会比uint8_t快
互斥都是通过开中断和关中断来实现的。 ruanxianwu 发表于 2015-6-25 11:02
嗯,uint8_t不一定比uint32_t快的。跟机器处理位数匹配的是效率最高的,STM32是32位的,所以uint32_t至少 ...
你说,互斥访问都用开关中断的方法。我重新查阅了《cortex m3 权威指南》(中文版),在95页,有LDREX/STREX 互斥访问的指令对。我的理解是:用汇编不需要开关中断就可以实现的。用C怎么实现?不懂了。 modbus 发表于 2015-6-25 10:30
楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成 ...
请问 32bit的单片机 ,加1减1也不是原子操作?
谢谢 弱弱的问一句,什么叫原子操作? guolun 发表于 2015-6-25 12:00
你说,互斥访问都用开关中断的方法。我重新查阅了《cortex m3 权威指南》(中文版),在95页,有LDREX/ST ...
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的
内存是独立于CPU的,STM32和51是不同的,STM32的CPU里面只有十来个寄存器。
一般情况下(特殊情况register暂不考虑),比如 i++,当你需要最这个变量进行操作,需要把i从内存中读回CPU的R0中,然后才是INC R0,然后再把R0写回到内存中。
所以不管你i是什么类型的。都是需要三个步骤才能完成一次操作的。假如你要保证他的原子性,i++之前关闭中断,然后再打开。这样就不会有其他中断抢占他了
涨姿势了{:smile:}
ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?
这么感觉不会呢
读
--------【此处被打断,不受影响】
修改
--------【此处被打断,不受影响】
写
谢谢 ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?
这么感觉不会呢
读
--------【此处被打断,不受影响】
修改
--------【此处被打断,不受影响】
写
谢谢 确实和有可能如楼主所说。32CPU 在处理 8bit ++ 时,在汇编的时候可能会做数据转换,影响性能 ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...
是三个步骤完成++操作,但是这三条指令之间被中断打断,并不会影响最后一条指令向内存中写入的值吧,所以我认为这个地方并不需要关中断进行保护,不知道理解的有没有问题? 823032003 发表于 2015-7-6 21:15
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?
这么感觉不会呢
我也觉得没问题 STM32 用uint_8编译出来的代码量比用 uint16_t/32_t 的大 wq_601840968 发表于 2019-7-24 09:26
我也觉得没问题
如果中断外减1条件和中断同时有效时,原子操作可保证这个变量值不变,而非原子操作的话这个变量值可能不变,也可能减1,而这种差异对程序有没有影响则要看具体程序要求了 涨姿势了! 学习了 823032003 发表于 2015-7-6 21:15
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?
这么感觉不会呢
(引用自19楼)
读
--------【此处被打断,不受影响】 !!别的进程修改这个变量
修改
--------【此处被打断,不受影响】 !!别的进程修改这个变量
写
最后写入就覆盖了中间的操作
页:
[1]