1、Ederson de SouzaOS Development Engineer20232 Footprint?Tools Common Hints Experiments Function pointers considered harmful Not really What about LTO?Ending thoughts Q&!A3 How big is the impact on some resource ROM/Disk/Flash RAM Power consumption Why do we care about it?Save resources Money EnergyWh
2、ere are we?4 But first,lets measure it Otherwise,improvements cant be proven Nor regressions detected Zephyr has a nice ROM report toolwest build-t rom_report56 Disable unused features/subsystems Avoid holes in structs west build-t pahole Limit number of threads Logging Power management Try differen
3、t toolchains78 Experimenting what we do So,we can ask if we do Not prescribing Some test were not checked on runtime So,things may be broken Used some open-source projects on the tests Not implying anything Focus on application size9 Compiler loses visibility on whats being used Dead code eliminatio
4、n misses Zephyr APIs extensively use them /Declaration _subsystem struct kscan_driver_api kscan_config_t config;kscan_disable_callback_t disable_callback;kscan_enable_callback_t enable_callback;/Driver instantiationstatic const struct kscan_driver_api kscan_npcx_driver_api=.config=kscan_npcx_configu
5、re,.enable_callback=kscan_npcx_enable_interface,.disable_callback=kscan_npcx_disable_interface,;10 Zephyr APIs extensively use them(II)/API usage _syscall int kscan_enable_callback(const struct device*dev);static inline int z_impl_kscan_enable_callback(const struct device*dev)const struct kscan_driv
6、er_api*api=(const struct kscan_driver_api*)dev-api;if(api-enable_callback=NULL)return-ENOSYS;return api-enable_callback(dev);11 What if we have something like C+templates?kscan?Could _Generic come to help?How to have the type at coding time?Maybe DTS can help here?Didnt explore this line further But
7、 it could be interesting12 But not all is lost Maybe have a static dispatcher table?Some macros,regex and code generation can help Lets try it!13 A script,gen_static_dispatch.py Basically,greps for the API instantiation and generate some functions int _static_kscan_npcx_enable_callback(const struct
8、device*dev)return kscan_npcx_enable_interface(dev);Also,generates a dispatcher for them,that the API can use static inline int z_impl_kscan_enable_callback(const struct device*dev)#ifdef CONFIG_STATIC_DISPATCH_KSCAN return static_dispatch_kscan_enable_callback(dev);#else(.)14 A script,gen_static_dis
9、patch.py(II)And the dispatcher static inline int static_dispatch_kscan_enable_callback(const struct device*dev)#ifdef CONFIG_KSCAN_NPCX extern int _static_kscan_npcx_enable_callback(const struct device*dev);return _static_kscan_npcx_enable_callback(dev);#endif return-EINVAL;Which we include in the d
10、river code#include static_dispatch_kscan_npcx.c15 What if theres more than one driver for the same subsystem enabled at the same time?Wed need some way to know the type of a device in runtime Another field on dev struct,some pointer tag,etc And a switch to chose the right API On preliminary tests,th
11、is the footprint So,experiments with static dispatching proceeded only when there was a single driver for a subsystem16 After some use of regex,got a few subsystems ready for testing ADC,Clock control,Display,ESPI,Flash,GPIO,IC,Kscan,PS2,PWM,Regulator,Sensor,UART,Watchdog Some open source projects Z
12、SWatch(https:/ Intel EC FW(https:/ ZMK*(https:/zmk.dev)Board:planck_rev6 As static dispatch work was done on Zephyrs main branch,those projects were rebased on top of it Zephyr SDK 0.16.117 ZSWatch Not really impressive,given size of application Still something,I guess Intel EC FW More interesting s
13、maller applications shall get more gainsNo static dispatchNo static dispatchStatic dispatchStatic dispatchDifferenceDifference%6293546284988560.1No static dispatchNo static dispatchStatic dispatchStatic dispatchDifferenceDifference%914789004714311.518 ZMK It actually got bigger!Looking at the report
14、,it seems some dead code was activated instead Not sure why,at the moment of writing this presentation If you know whats going on,let me know!But it gives some inspiration to go a bit further.No static dispatchNo static dispatchStatic dispatchStatic dispatchDifferenceDifference%3473935411-672-1.919
15、Ultimate dead code elimination Old dream https:/ Reports of downstream use Basically,add-flto=auto-ffat-lto-objects west build b -DEXTRA_CFLAGS=-flto=auto-ffat-lto-objects Need a few patches on Zephyr Mainly,add _used to some functions and variables20 ZSWatch Intel EC FW ZMKBeforeBeforeStatic dispat
16、ch(gain/%)Static dispatch(gain/%)LTOLTO(gain/%)(gain/%)LTO+Static DispatchLTO+Static Dispatch(gain/%)(gain/%)629354628498(856/0.1)627465(1889/0.3)626553(2801/0.4)BeforeBeforeStatic dispatch(gain/%)Static dispatch(gain/%)LTOLTO(gain/%)(gain/%)LTO+Static DispatchLTO+Static Dispatch(gain/%)(gain/%)9147
17、890047(1431/1.5)81436(10042/11.0)78912(12566/13.7)BeforeBeforeStatic dispatch(gain/%)Static dispatch(gain/%)LTOLTO(gain/%)(gain/%)LTO+Static DispatchLTO+Static Dispatch(gain/%)(gain/%)3473935411(-672/-1.9)30092(4647/13.4)30728(4011/11.5)21 LTO provides biggest gains Is static dispatch really useful?Interesting gains How to implement it?Not sure macros+code generation is the way Could devicetree help something more like templates?Need to ensure things do work!No subtle bugsFind me on Zephyr Discord:edersondisouza#9895202323*Other names and brands may be claimed as the property of others