Go Down

Topic: post-UNO world of 32-bit uC's with 20K or more of SRAM (Read 2487 times) previous topic - next topic

Robin2

The title is a quote from this very interesting Post.

I don't have any experience of the faster chips and I have not yet had a project that could not be satisfied by a 16MHz (or 8MHz) Arduino.

However it seems increasingly likely that newbies will jump straight in with newer faster chips with lots of SRAM and it makes no sense to recommend to them restrictions that are only appropriate for an Uno or Mega.

At the same time, programs for an Uno or Mega must respect the limited capabilities of those chips.

Perhaps there is now a need to make a clearer distinction between the 16MHz Arduinos and faster chips with much more SRAM.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

westfw

Meh.  New users don't use AVR Arduinos because they're the best available microcontrollers.  They use them because they have an unprecedented amount of documentation, tutorials and examples, plus a helpful community.  If they're going to use a "faster chip with lots of RAM", perhaps they'll need a new forum/etc.

(I can also find plenty of embedded systems programmers, and I think some "industry standards" that will tell you that using dynamic memory allocation in an embedded system is evil and forbidden, regardless of the amount of RAM.  I think that they're behind the times, a bit.  OTOH, I can assure you that "memory fragmentation" is a real problem even in systems with multiple megabytes of RAM.  And memory allocators get more and more complicated to try to avoid such problems.  (the last "real" system I used had malloc memory, chunk memory, element pools, and several different packet pools (it was a network device.)  I wish someone would just FIX THE STRING CLASS so that it has easily explainable limitations, rather than this vague "sometimes it might cause problems" nonsense...)


OldSteve

I can also find plenty of embedded systems programmers, and I think some "industry standards" that will tell you that using dynamic memory allocation in an embedded system is evil and forbidden, regardless of the amount of RAM.  I think that they're behind the times, a bit.  OTOH, I can assure you that "memory fragmentation" is a real problem even in systems with multiple megabytes of RAM.  And memory allocators get more and more complicated to try to avoid such problems.
Behind the times or not, to me, this implies that beginners should avoid dynamic allocation unless it's absolutely necessary, because of the potential problems that you mention. And most people who come to these forums asking questions are beginners.
Please do not PM me for help. I am not a personal consultant.
And others will benefit as well if you post your question publicly on the forums.

OldSteve

I had replied, but changed my mind, since this is a discussion purely on the larger MCUs and not at all relevant to UNO or other '328P boards.
Please do not PM me for help. I am not a personal consultant.
And others will benefit as well if you post your question publicly on the forums.

-dev

Sigh.  One year later.

Quote from: MrBurnette
I just do not see any real problems in the core String class.
Please, please, please follow the links below to help you understand the real problems:

Here is the generic problem in the Arduino ecosystem.  Beginners have very little chance of using the heap safely.  It is deceptively easy to use, which is the pitfall.  Here is the typical life cycle.

Tongue firmly in cheek and from two perspectives, here are some of the consequences.

Quote from: westfw
OTOH, I can assure you that "memory fragmentation" is a real problem even in systems with multiple megabytes of RAM.
Truth.  Here is a summary of the issues from the innertubes.  No, not even on servers.

There are many inarguable reasons not to use the heap, and there are no unique reasons to use the heap, regardless of platform.  Everybody's time will be better spent by discouraging its use and suggesting more reliable and efficient techniques.  With a good foundation, their sketch will work now and in the future.

Cheers,
/dev
Really, I used to be /dev.  :(

Robin2

Here is the generic problem in the Arduino ecosystem.
Isn't the discussion in that link about programming a 16MHz Arduino?

People use the String class and even more elaborate abstractions every day when programming on a PC generally without problems. For example, I do my PC programming with Python or JRuby.

How do you distinguish between platforms where the String class can be used safely and those where its use is unwise?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

westfw

STL for everyone?  Semi-real operating systems that clean up after individual applications (and a new structure encouraging short-lived applications instead of monolithic individual programs)?  Some languages other than C/C++?

Where do you just say "bah!  I'm jumping to a Raspberry Pi or something else that runs unix and my choice of HLLs"?


westfw

Those were more suggestions to the topic in general, than to your post specifically.
What should we do with more powerful processors?  Add more overhead, of course!

Take the following suggestion that appeared recently:

Quote
I would recommend to add the following hint in the documentation of Serial.print() to make things easier for beginners:

Code: [Select]
Serial.println((String)"The value is "+3.7+"V");
When do you think that that would be a good idea?
The "intro to Python" classes I'm taking all think that it's fine...

Robin2

Where do you just say "bah!  I'm jumping to a Raspberry Pi or something else that runs unix and my choice of HLLs"?
I must say that is the first thought that comes to my mind when I read about high-speed microprocessors with huge amounts of ram (compared to an Atmega 328).

I can see it might be different if you were designing a product for 1,000,000 plus production units - but that is NOT the focus of this Forum.

And to be honest I'm not sure why one would even waste time with an RPi - just use a cheap laptop. I guess an RPi would be useful for a project where you need minimal energy consumption.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

westfw

Quote
I guess an RPi would be useful for a project where you need minimal energy consumption.
Ah.  Low power.  AFAIK, even something like a Due uses much less power than an RPi.


Robin2

Ah.  Low power.  AFAIK, even something like a Due uses much less power than an RPi.
But (AFAIK) it cannot run Linux.

And. presumably, an Atmega 328 or 2560 uses even less power.

Of course there may be a case for writing complex programs on microprocessors without operating systems if there really is a need for very low power - although mobile phones seem to challenge that assumtion.

But, do very low power applications really need to be so complex that an Atmega 328 or 2560 can't cope?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

-dev

Quote from: Robin2
Isn't the discussion in that link about programming a 16MHz Arduino?
Not that I can find.  It just says "I have a Arduino sketch..."  All the replies are generic, as are the other links from above.  Without re-checking all the linked links, I couldn't say everything is generic, but the great majority certainly is, even Majenko's nicely written "The Evils of Arduino Strings."

Quote from: Robin2
People use the String class and even more elaborate abstractions every day when programming on a PC generally without problems.  For example, I do my PC programming with Python or JRuby.
Yes, that's what is so deceptive.  Dynamic "things", including String, are very convenient and easy to use.  But everybody knows that you should probably reboot when your PC seems a little sluggish.  Guess why it starts to slow down, and guess why the reboot fixes it.  A PC is the nicest environment, and the problem still manifests.  Most people don't care, because rebooting once a day is No Big Deal.  OTOH, if you need your server to run forever, it's a Very Big Deal, because rebooting will be required just when it causes the most inconvenience.  :)

Contrast that with a more-constrained environment: 100k RAM is still a pittance, and "reboots" to defragment memory could be required much, much more frequently than the PC.  Most Arduino users do not expect to reboot, so why suggest a technique that will probably require it? 

Quote from: mrburnette
I have not seen and do not see in other forums the types of issues being described here.
I don't think you will ever see that.  Failures due to fragmentation are seriously "under-reported", because most users will not be able to correlate a symptom with the cause, especially in low data-rate applications.  And the impact of a failure may be no more than "Hmm, must be a power glitch."

Yes, it is possible to use dynamic memory safely.  But it usually requires a level of care that a beginner cannot exercise.  By the time they can exercise the care, they probably know of other techniques (e.g., pools).  Anyone who understands the problem does not have to ask, "Why is my memory fragmented?", so you'll never see the question.  Also, that code is fragile: changing one line of code can affect the lifetime of dynamic objects.  This is particularly troublesome for anyone who later tries to modify the sketch for their own use.

I am particularly amused when I see "careful" code like this:

Code: [Select]
  uint8_t *buf = malloc( n );  // or String buf;
      <do something with buf>
  free( buf ); // or buf destroyed at end of routine

Please, just do this:

Code: [Select]
  {
    uint8_t buf[n];
     <do something with buf>
  }

Um, excuse me, but you really didn't have to call malloc to search for some free memory.  It was right next to you on the stack.  :D

Quote from: Robin2
How do you distinguish between platforms where the String class can be used safely and those where its use is unwise?
You could use dynamic memory unsafely if there is a low cost for resetting at some periodic interval (is that what the Watch Dog Timer is for?  o_O), or if there is a low cost for a failure during operation and later in identifying and fixing the failure.

You could use dynamic memory safely if maximum lengths are enforced, operations are guarded against malloc failures, lifetimes have been analyzed and a "soft" degradation in functionality is acceptable.  (See also this answer.  Suggestion 4 turns this the heap into a pool.)

Conversely, you cannot use dynamic memory if you expect it to run forever, or if you won't be able to identify the failure (Don't come crying to me.  ;) ).  There is also a memory cost to consider:  The String class adds 1600 bytes to the program size and 10 bytes to every String variable.

This is the essence: Most Arduino users fall into the latter category, and they don't know that they won't be able to identify the problem.  Many experts can perform the analysis required by the former categories, but have learned that the ease-of-use during coding is far outweighed by the required analysis and subsequent debugging and modification costs.

Cheers,
/dev
Really, I used to be /dev.  :(

Robin2

Not that I can find.  It just says "I have a Arduino sketch..."  All the replies are generic, as are the other links from above.
Well perhaps that goes to the heart of the reason I started this Thread.

I generally assume that questions on the Forum are about UNOs, Megas, Micros etc (i.e. 16MHz Arduinos with very limited SRAM).

I had assumed that @mrburnette was suggesting that restrictions that are necessary on the small MCUs can be relaxed on those with more speed and more SRAM

I guess your long Post is saying that the same risk of crashes due to memory fragmentation exists on all computers. Is this true even with the programming languages that include automatic garbage collection?

And I certainly don't have the experience to contradict you. My laptop is restarted a few times every day.

It's quite a while since I regularly read stuff about web development but I can't recall any mention of a requirement to restart servers as a matter of course to "clean up" after fragmentation. There were plenty of other things that could go wrong :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

-dev

#13
Sep 19, 2016, 06:39 pm Last Edit: Sep 19, 2016, 09:38 pm by /dev Reason: grammar
Quote
the same risk of crashes due to memory fragmentation exists on all computers.
Yes.  The ratio of used memory to free memory affects how quickly the slowdown (or "thrashing") occurs.  This is also why memory leaks are hunted down with vigilance.  A leak will increase the ratio of used to free memory, leading to a quicker slowdown.  This is also why using the heap seems to behave better on systems with "more" RAM (a mind-boggling 96KB, LOL).  The slowdown takes longer, or it is not recognized.

And, to be clear, careful programming (i.e., in the apps and the OS) can mitigate that risk significantly.  There is some additional risk when the code has to be modified, because the same care must be constantly applied to the modifications.

Quote
Is this true even with the programming languages that include automatic garbage collection?
I've been wondering if this topic would come up.  Garbage Collection is just an automatic way to free memory.  In the Arduino, you must explicitly call free for everything you malloc.  String performs its own garbage collection, in that the destructor frees the memory it is using.  The lifetime of the String is the maximum lifetime of the dynamic memory it uses.

You could write code for the Arduino that performs garbage collection for things that are no longer used.  Reference counting is a common technique for that.  Basically, when an integer member of a class is decremented to zero, it deletes itself.  o_O  Just be sure the integer is always correctly decremented.  -_-

So yes, systems that implement Garbage Collection still experience the problem, because GC does not eliminate fragmentation.  It is really intended to eliminate memory leaks and to relieve the programmer from having to explicitly free resources.  It is also difficult to decide when to perform the GC.  Many dissertations have been written on this subject.

Eliminating fragmentation requires other techniques.  I've already mentioned pools, but double indirection (e.g., handles) can be used to relocate memory for reducing fragmention (think Disk Defrag).  This obviously incurs a penalty for accessing (extra pointer reads), but it is especially expensive during a relocation.  When should that happen?

Quote
And I certainly don't have the experience to contradict you.  My laptop is restarted a few times every day.
LOL, I think you have the experience to agree with me, as do many Windoze users.  :)

Cheers,
/dev
Really, I used to be /dev.  :(

Robin2

I've been wondering if this topic would come up.  Garbage Collection is just an automatic way to free memory. 
I was not trying to suggest that someone should write a system for automatic garbage collection on an Arduino. That probably makes even less sense than trying to write an Operating System for an Arduino.

I was trying to get your opinion about the "safety" of using languages that have in-built GC on a PC?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up