Different pool memory consumption in sim and bare metal

I run the same firmware with minimal differences on PC (with sim drivers) and bare metal. It has “monitor”, printing lvgl memory use (on bare metal - wia retargeted stdout to USB CDC).

Problem is, memory use difers significantly, while it’s expected to be platform-independent. Here are real value with displayed lists of 6 and 16 elements (with custom drawers):

hw 6 items:   [Memory] total: 6144 bytes, free: 4088 bytes, use: 34% (2056)
hw 16 items:  [Memory] total: 6144 bytes, free: 3088 bytes, use: 50% (3056)

sim 6 items:  [Memory] total: 6144 bytes, free: 2832 bytes, use: 54% (3312)
sim 16 items: [Memory] total: 6144 bytes, free: 1072 bytes, use: 83% (5072)

On bare metal each item adds 100 bytes. On sim - 170 bytes. WTF?

Of cause, PC platform is x64, while stm32 - 32 bits. Can this cause so big difference and if yes, is it possible to workaround? I use sim intensive, and would like it reproduce lvgl pool use more close to real hardware.

  • What are the differences between the platforms’ lv_conf.h files? Do you have some features enabled on the PC simulator that aren’t enabled on the real hardware? Are the color depths the same?
  • You should definitely compile the PC simulator as a 32-bit application (-m32) if you want the results to be similar, as there are a number of pointers stored in the heap.

There are no difference in lvgl config. Since i’m not interested in pitfails, application has hal layer to keep differences as minimal as possible.

As far as i understand, lvgl has internal allocator implementation for it’s heap, and in theory it’s possible to force it work the same way everywhere. No?

I tried to use -m32 and got huge number of different errors. What i did:

sudo apt-get install gcc-multilib g++multilib
# sdl packages conflict, remove native
sudo apt-get remove libsdl2-dev
sudo apt-get install libsdl2-dev:i386

Now reached linking stage, and has errors about not found/incompatible libs, no idea how to fix. Also tried -Wl,-march_i386 in global build flags.

Could you help? I use Ubuntu 18.04LTS.

IMO, this issue needs more care in doc, because it’s importand to have “similar” memory behaviour while develop most of project on PC. Should i create issue in tracker or nobody except me interested in?

The internal allocator works the same way, but pointers are twice the size on 64-bit computers (no way to change that), so it’s impossible to get identical behavior if one platform is 64-bit and another is 32-bit.

I haven’t heard of anyone else trying to do what you’re trying to do, so I have no idea if anyone requires this.

Personally, I would do the math and see if the memory consumption increased by a similar amount on both platforms. For 6 items, the ratio between hw and sim is 1:1.61. For 16 items, it’s 1:1.66. Those seem similar to me, so if you just divided all numbers you got from the simulator by 1.6, that should be good enough for your use case.

It’s not a problem to just define 1.7x more space for sim build. But it’s not convenient to keep such things in mind. If it’s possible to make heap behave the same way as on stm32, that would be convenient.

I need that for PlatformIO, but working Makefile example would be enougth. Also, worth to mention in std2 docs about different heap requirements.

I don’t think it requires mentioning in the documentation, mainly because it’s just an inherent feature of C on different platforms. A 64-bit program will always need more memory than a 32-bit one, regardless of whether LittlevGL is involved.

To know this thing, user must keep in mind difference between platforms and know lvgl heap store pointers (because data structs can be designed to not store those, as binary font format).

I could avoid some optimizations, if know about heap in advance. I found this difference by accident at all, because decided to add USB CDC just for fun.

On 64 bit systems, lvgl uses 8-byte alignments instead of 4 byte. I’ve added it intentionally once because there were issues due to the misaligned memories.

I agree to some extent because now you can’t simulate your project precisely. However, e.g. lv_style_t * style in lv_obj_t will also use 8 bytes instead of 4. So the size of every object will be different regardless of the memory allocator.

If you plan to resolve that, i see 2 possibilities:

  • Styles can be refered via index id instead of direct pointers
  • Create manual how to install/build project with sdl2 in i386 mode.

Or, simply document the relative memory size difference, which involves the least changes to the code and still lets you accurately measure how much memory will be used.

For clarity, it should be really mentioned somewhere.

I was able to compile it like this:

  • Install 32 bit SDL: sudo apt-get install libsdl2-dev:i386
  • GCC Multilib: sudo apt-get install gcc-multilib (if not working install g++-multilib too )
  • Add -m32 to compiler and linker flags too

If you can confirm it works we can add a few lines of description about it in the README.