MALLOC_CAP_32BIT and float

nitski
Posts: 2
Joined: Fri Mar 23, 2018 12:33 pm

MALLOC_CAP_32BIT and float

Postby nitski » Fri Mar 23, 2018 12:42 pm

Hello all,

Is float type capable for MALLOC_CAP_32BIT ?

I used simple the code :

Code: Select all

float *test=(float *) heap_caps_malloc(sizeof(float)*10,MALLOC_CAP_32BIT);
for(i=0;i<10;i++)test[i]=i;
It causes to LoadStoreError. With int it works fine...

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: MALLOC_CAP_32BIT and float

Postby kolban » Fri Mar 23, 2018 3:21 pm

Howdy,
Ive been horribly wrong in a lot of my posts recently but, undeterred in flaunting my ignorance ... my answer would be "sure that works fine". My understanding is that MALLOC_CAP_32BIT allocates storage from the heap aligned to 32bit boundaries. For example, if one called it 5 times allocating 1 byte, then the 20 bytes would be taken from the heap.

We would want to look and see how many bytes a float would be ... but I'm going to guess 32 or 64 bits.

The first test I can think of is to examine the return value from heap_caps_malloc(). Make sure it isn't NULL. If (for some reason) you asked for 80 bytes (sizeof(float) * 10 = 8 * 10 = 80) and there wasn't 80 bytes of contiguous storage available then you would get NULL and an attempt to write into NULL[0] would fail.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: MALLOC_CAP_32BIT and float

Postby ESP_Sprite » Sat Mar 24, 2018 2:00 am

I think it's not capable of doing that. The MALLOC_CAP_32BIT is a bit misleading: the actual reality is that only L32I/S32I instructions can access this memory to retrieve data, and those instructions are only capable of loading integer values.

kindaTall
Posts: 6
Joined: Mon Jan 20, 2020 4:21 pm

Re: MALLOC_CAP_32BIT and float

Postby kindaTall » Thu Nov 17, 2022 3:03 pm

I realize this is super old. But I just ran into this problem today.

I was wondering if this has been fixed in newer versions. We are currently still on 4.4 and are running into this issue.
Though I expect this to be a silicon issue tbh.

We are currently working around this, by casting the malloced float array to int32_t, then reading or casting the address of the float value, which we want to write, to an int32_t pointer and then writing the value of that integer.
But this is all very ugly.

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: MALLOC_CAP_32BIT and float

Postby ESP_igrr » Thu Nov 17, 2022 10:55 pm

Hi kindaTall,
Allocating MALLOC_CAP_32BIT memory may (on the ESP32) give you part of Instruction RAM, which is not usable for floating-point operations. If you intend to store floats, i would suggest using MALLOC_CAP_DEFAULT.

(On chips other than the ESP32, no Instruction RAM is added to the heap allocator, so all the allocated memory is Data RAM, and this issue does not occur.)

kindaTall
Posts: 6
Joined: Mon Jan 20, 2020 4:21 pm

Re: MALLOC_CAP_32BIT and float

Postby kindaTall » Mon Nov 21, 2022 9:10 am

Hello ESP_igrr,

Thank you for your quick response. For now, I have shifted and optimized some allocations, so that we have sufficient 8B capable memory.
I realize the error may be niche, but I think it might warrent an update in the documentation.

This workaround seems to also work, though I understand it will be less efficient:
  1. void write_to_32_bit_malloc(float * dst, float * src, size_t len){
  2.     int32_t * dst_i = (int32_t * ) dst;
  3.     for(int i = 0; i < len; i++){
  4.         dst_i[i] = *(int32_t*)(src + i);
  5.     }
  6. }
Is it in anyway possible to implement something like this on the backend, so that write/reads to Instruction RAM are never floating-point operations, but instead take this detour?

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: MALLOC_CAP_32BIT and float

Postby ESP_igrr » Fri Nov 25, 2022 7:24 am

kindaTall wrote: Is it in anyway possible to implement something like this on the backend, so that write/reads to Instruction RAM are never floating-point operations, but instead take this detour?
I think it is possible, in theory. However given the fact that this workaround is only necessary for the ESP32 chip, I don't think it's likely that we will implement it. In newer chips, the memory layout is more linear and there is no need to allocate memory from IRAM.

Who is online

Users browsing this forum: No registered users and 145 guests