Re: Constant GC allocations when sending large messages to threads?
On 2/2/20 12:13 PM, cc wrote: On Friday, 31 January 2020 at 15:47:26 UTC, Steven Schveighoffer wrote: You could use RefCounted to build a struct that then is sendable with the data you need. RefCounted allocates using C malloc, not the GC. Thanks for the tips. How exactly would I go about sending a RefCounted value? static struct Foo { int a; @disable this(this); } auto t = RefCounted!Foo(Foo(5)); tid.send(t); Gives me: phobos\std\concurrency.d(625): Error: static assert: "Aliases to mutable thread-local data not allowed." Whereas trying to declare it as immutable gives me a pile of errors including: Error: mutable method `std.typecons.RefCounted!(int, cast(RefCountedAutoInitialize)1).RefCounted.__postblit` is not callable using a `immutable` object Ugh, I think it should be doable. But I don't have time right now to try and figure it out. The idea would be to send an immutable/shared piece of data that's refcounted across to another thread. If send is rejecting that, or refCounted is not playing nice, maybe file some bugzilla issues. -Steve
Re: Constant GC allocations when sending large messages to threads?
On Friday, 31 January 2020 at 15:47:26 UTC, Steven Schveighoffer wrote: You could use RefCounted to build a struct that then is sendable with the data you need. RefCounted allocates using C malloc, not the GC. Thanks for the tips. How exactly would I go about sending a RefCounted value? static struct Foo { int a; @disable this(this); } auto t = RefCounted!Foo(Foo(5)); tid.send(t); Gives me: phobos\std\concurrency.d(625): Error: static assert: "Aliases to mutable thread-local data not allowed." Whereas trying to declare it as immutable gives me a pile of errors including: Error: mutable method `std.typecons.RefCounted!(int, cast(RefCountedAutoInitialize)1).RefCounted.__postblit` is not callable using a `immutable` object
Re: Constant GC allocations when sending large messages to threads?
On 1/31/20 2:14 AM, cc wrote: On Wednesday, 29 January 2020 at 21:10:53 UTC, Steven Schveighoffer wrote: I'm pretty sure std.concurrency uses Variant to pass message data, which boxes when it gets over a certain size. You are probably crossing that threshold. The allocations should level out eventually when the GC starts collecting them. Is there a way to pre-allocate a buffer or something to be used? Ideally I'd like to avoid too many garbage collections happening, in my application these thread messages happen almost every frame and are quickly adding up to 100s of kilobytes in allocations every few seconds. You could use RefCounted to build a struct that then is sendable with the data you need. RefCounted allocates using C malloc, not the GC. It might actually be reasonable to modify std.concurrency to use RefCounted instead of GC memory (i.e. it needs to be a specialized Variant). -Steve
Re: Constant GC allocations when sending large messages to threads?
On Friday, 31 January 2020 at 07:14:30 UTC, cc wrote: On Wednesday, 29 January 2020 at 21:10:53 UTC, Steven Schveighoffer wrote: I'm pretty sure std.concurrency uses Variant to pass message data, which boxes when it gets over a certain size. You are probably crossing that threshold. The allocations should level out eventually when the GC starts collecting them. -Steve Is there a way to pre-allocate a buffer or something to be used? Ideally I'd like to avoid too many garbage collections happening, in my application these thread messages happen almost every frame and are quickly adding up to 100s of kilobytes in allocations every few seconds. You can just allocate non-GC memory.
Re: Constant GC allocations when sending large messages to threads?
On Wednesday, 29 January 2020 at 21:10:53 UTC, Steven Schveighoffer wrote: I'm pretty sure std.concurrency uses Variant to pass message data, which boxes when it gets over a certain size. You are probably crossing that threshold. The allocations should level out eventually when the GC starts collecting them. -Steve Is there a way to pre-allocate a buffer or something to be used? Ideally I'd like to avoid too many garbage collections happening, in my application these thread messages happen almost every frame and are quickly adding up to 100s of kilobytes in allocations every few seconds.
Re: Constant GC allocations when sending large messages to threads?
On 1/29/20 2:48 PM, cc wrote: Given the sample program at https://pastebin.com/u9sSNtj7 I'm experiencing GC allocations with every call to std.concurrency.send when sending larger messages (e.g. multiple ulongs). These do not occur when sending uints in comparison, in the provided example. For example, when the ManyAllocations version is set, I see results like: allocations: 100 bytes: 3280 When commented out, I see: allocations: 1 bytes: 80 Is there a way to mitigate this memory usage? Using DMD32 D Compiler v2.089.1-dirty on Windows 10 x64 cmdline: rdmd.exe -m64 I'm pretty sure std.concurrency uses Variant to pass message data, which boxes when it gets over a certain size. You are probably crossing that threshold. The allocations should level out eventually when the GC starts collecting them. -Steve