manager std:string on audio thread: safe?
- KVRist
- Topic Starter
- 180 posts since 18 Nov, 2017
Hi there,
I'm going to make a sequencer which will convert some specific patterns (defined as std: string) in notes (midi/cv/trigger signal, basically).
Question is: working with std:string (such as split, add/sub, convert to int) is safe for audio thread? Or does it could involve heap/memory allocation at runtime (= glitch)?
Note: it will processed/generated only when pattern start/restart (so once every x samples), but not sure this has some meaning (heap allocation for a single sample is bad in any case).
Thanks for any hints.
I'm going to make a sequencer which will convert some specific patterns (defined as std: string) in notes (midi/cv/trigger signal, basically).
Question is: working with std:string (such as split, add/sub, convert to int) is safe for audio thread? Or does it could involve heap/memory allocation at runtime (= glitch)?
Note: it will processed/generated only when pattern start/restart (so once every x samples), but not sure this has some meaning (heap allocation for a single sample is bad in any case).
Thanks for any hints.
- KVRist
- 296 posts since 1 Apr, 2009 from Hannover, Germany
Out of the box, std::string will likely allocate/deallocate unless you're very careful (creating them outside the audio thread, only doing safe stuff like reading on the audio thread).
But note that std::string is a specialization of the template std::basic_string, which supports custom allocators. So you could probably use a custom allocator or a std::polymorphic_allocator with enough pre-allocated space for strings on the audio thread.
However, is it really strictly necessary to process those strings on the audio thread? If they're created from some GUI interaction you could process them in the message thread into some symbolic or object representation that tells the DSP code what to do through a message queue or something (e.g. notes, parameter changes). Similarly, if the strings need to be created from audio analysis, you could go the other way around. What you're writing doesn't sound like the strings need to actually live on the audio thread.
But note that std::string is a specialization of the template std::basic_string, which supports custom allocators. So you could probably use a custom allocator or a std::polymorphic_allocator with enough pre-allocated space for strings on the audio thread.
However, is it really strictly necessary to process those strings on the audio thread? If they're created from some GUI interaction you could process them in the message thread into some symbolic or object representation that tells the DSP code what to do through a message queue or something (e.g. notes, parameter changes). Similarly, if the strings need to be created from audio analysis, you could go the other way around. What you're writing doesn't sound like the strings need to actually live on the audio thread.
- KVRAF
- 7899 posts since 12 Feb, 2006 from Helsinki, Finland
You probably should not. Even if the patterns are input as strings, you should probably parse (and store) them as some easier to handle binary data right where they are input. You should typically do this even if there was no real-time considerations to worry about, because this allows you to isolate all the string handling in one place and rest of your code does not need to worry about whether the strings actually contain valid data.
Whether or not you actually should do it (you should not), you can safely access the contents of the string, but pretty much anything that actually changes the string will cause an allocation and therefore potentially a glitch. If you're working with recent enough C++ standard then I'd imagine you could perhaps split strings by creating the substrings as stringviews, which is basically a range over character data... but honestly you should probably do all this stuff (strings or not) in GUI thread and just pass the final results to the audio thread if possible.Question is: working with std:string (such as split, add/sub, convert to int) is safe for audio thread? Or does it could involve heap/memory allocation at runtime (= glitch)?
Any amount of memory allocation in audio thread is a potential problem... and in fact when you allocate, you typically end up also deallocating previous chunks and that's also potentially risky.Note: it will processed/generated only when pattern start/restart (so once every x samples), but not sure this has some meaning (heap allocation for a single sample is bad in any case).
The issue here is that the way memory allocators are designed, they try to be as efficient as possible on average and it's the on average part that's a problem for real-time. Most memory allocations (and deallocations) will be satisfied quickly (unless the allocator really sucks) and will not cause a glitch... but then once in a while it'll happen that the memory allocator doesn't just have the correct size block waiting for you and needs to go and start doing more complicated things... or just randomly decides to do a bit of cleanup or bookkeeping maintenance or whatever... and it's the "once in a while some allocation can be really slow" that is the real problem for a real-time thread, because real-time threads don't care about averages, they care about hitting their deadlines.
In other words, when you allocate, most of the time the allocator grabs a block from a freelist and that's it. Most of the time when you deallocate it puts that block back to the freelist and that's it... but if you build a memory allocator that only ever does this, you'll find that it performs poorly on average, because the heap will get all fragmented.. and that's why memory allocators have to do a bit more and if they decide to do that "bit more" when it's your realtime thread calling, that's a glitch.
-
- KVRian
- 919 posts since 4 Jan, 2007
Everyone is correct.
I want to add that on some 64 bit platforms you might get away with strings under 23 bytes not allocating at all because of short string optimization.
https://stackoverflow.com/questions/216 ... on-in-libc
Totally platform and stdlib implementation dependent. Probably not testable at compile time. Rely on it at your own risk.
I want to add that on some 64 bit platforms you might get away with strings under 23 bytes not allocating at all because of short string optimization.
https://stackoverflow.com/questions/216 ... on-in-libc
Totally platform and stdlib implementation dependent. Probably not testable at compile time. Rely on it at your own risk.
-
- KVRer
- 4 posts since 10 Feb, 2024
Just to maintain the discussion, with C++20, you can get some insight into the short string optimization by declaring a constexpr std::string global variable and looking at which point the compiler stops allowing it. Visual Studio is particularly funny about it; right now it allows me up to 15 characters, but only in non-debug mode (not /MDd).