How to develop on the stack with Nim?
Asked Answered
S

3

5

I would like to use Nim in a soft-realtime context, where both memory allocation and garbage collection exhibit too much latency. Therefore, manual memory management is desirable- or, even better, working exclusively from stack memory.

Which subset of Nim can I work from in order to achieve stack only memory allocation? I am guessing I can tell it worked by the absence of a memset or memcpy in the cached C code.

Swithin answered 23/2, 2018 at 13:46 Comment(0)
B
7

If you really want to go without garbage collection, you need to use the --gc with the none parameter, as explained in the Nim Compiler User Guide. The none parameter disables the garbage collector, leaving you on your own. This usually means any string operations will produce a warning, because despite memory being allocated, nobody is freeing it later:

proc main() =
  let x = 5
  echo "Hello " & $x & " there"

main()

If you compile this little test with nim c --gc:none -r test.nim you will get the gc warnings:

test.nim(3, 19) Warning: '$ x' uses GC'ed memory [GcMem]
test.nim(3, 22) Warning: '&("Hello ", $ x, " there")' uses GC'ed memory [GcMem]

This can help you catch which parts of Nim are safe to use in a GC-less environment, either directly or indirectly. Note, however, that certain operations can be moved to the compilation phase. As such, the following example producing the same output is safe to use without GC because all the const expressions are allocated statically by the generated C code:

proc main() =
  const x = 5
  echo "Hello " & $x & " there"

main()

Looking inside the nimcache directory you will find the source contains a line similar to this:

  STRING_LITERAL(TM_ipcYmBC9bj9a1BW35ABoB1Kw_2, "Hello 5 there", 13);

Still, note that in the documentation mentioned above there is a link to Nim's Garbage Collector documentation, which contains a very specific Realtime support section which might be of help, and possibly avoid you the pain of handling manually memory if the compromise it offers meets your requirements.

Bough answered 23/2, 2018 at 18:1 Comment(0)
E
1

Well currently both string and the seq type require a GC to work properly even though they have value type semantics. This however is planed to be changed. I just can't tell you when this is. And without those two types, Nim isn't really a language you would want to use. Apart from that types wrok pretty much like in c++. So if you don't use ref types there will be no further allocation for the GC.

Elburt answered 28/3, 2018 at 23:19 Comment(0)
A
1

Not Nim specifics, neither GC specifics, and neither am I going to provide a reasonable answer here, but rather a language agnostic programming advice.

The stack is limited, to a MiB, or 24KiB on Android. You can make it 8MiB maybe by tweaking manifests left and right.

If you have no OS, in a real mode & non virtualized memory space, maybe you'll have an unlimited stack.

But most of real world applications would have to use an allocator. Reserve a block of memory on the heap, and keep a custom "stack pointer" that you can increment/decrement manually, by contrast of usually letting the compiler do it.

This brings 2 advantages: decoupling from the call stack and block scopes. And unlimited memory.

Limitation: on linux your pages are going to be zero filled on demand. The kernel provides pages lazily so you will experience stutter in critical time. To avoid this, prepare one sweep pass of writing 0xff on your whole space. This will have the disadvantage of being very not cooperative with other processes, and potentially trashing the filesystem cache. But for real time applications that's usually accepted by users.

Abdication answered 2/4, 2018 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.