On a lark I have been working on a new and improved "rapidxml" utilizing PMR memory resources instead of the implementation of a memory pool that library used. Its a great use case for the monotonic buffer resource. But I am not a developer, I just do it for fun, so I doubt its very good.
PMR is great but the real issue is how data is manipulated. At work we replaced picojson's strings with properly sized SSO strings, string views where possible, and better hash maps (gosh all of std::map/set are so bad and do tons of allocations per entry) and we earned a factor higher than 10 times faster. nlohmann's json library is slow because of the same issue, it's designed for correctness, but is using bad containers. Sure, PMR will surely help a bit, but that's like masking the core issue. Reduce the number of allocations before using PMR.
Really enjoyed the video. I've had a longtime interest in real applications of custom allocation strategies. Finding good teachable examples has always been difficult and are appreciated. A minor comment for future videos: please turn off the automatic cursor selection blame feature in your editor. I found it to distract from the code itself.
The winking out would be interesting if you could nest memory resources. Bc then you could just wink out subsections of the JSON and reallocate within the same memory resource.
Hi Jason! 1. Have you tried using tcmalloc? How does it compare with PMR? My experience is that tcmalloc is really fast and you do not not the burden of using PMR allocators (in most of the cases?) 2. How does PMR allocators interact with sanitizers and valgrind? As these allocators bypass the standard allocators that valgrind/sanitizers instrument, memory access errors probably cannot be catched and you need to use the new/delete allocator when running with these tools, so probably something like '#ifdef DEBUG #else #endif', and this, everywhere you use these non-default allocators.
1. tcmalloc is good, and will get you some gains, but it can never be as good as a custom tuned strategy provided with PMR. 2. PMR should not interfere with the sanitizers/valgrind at all. They never bypass allocation, they just do larger allocation in blocks. But I haven't done an exhaustive test of that.
Concerning the sanitizers, what I meant is that they are not aware of these allocators. This means for example that valgrind will not be able to catch uninitialized memory reads if that memory was already allocated and then released by the allocator but the underlying memory is still in used by the allocator itself, i.e. it has not been released to the OS. Reads or writes outside of array bounds may also be missed, as well as memory access after free, double free, ....
Concerning tcmalloc, my understanding is that it's basically a thread-safe memory pool, so it should have similar performance as std::pmr::synchronized_pool_resource (and maybe even better as I think it has pools per threads, so synchronization is needed only when releasing memory that was allocated in another thread).
The winking out discussion is actually two episodes ago, #250 starting at about 15:29. This should link to the correct timestamp: ua-cam.com/video/5VrX_EXYIaM/v-deo.html
PMR only helps when a library was designed without allocation performance in mind, and it often is shown directly in the API. Returning std::string? Almost always bad. Simdjson does almost no allocations so it wouldn't win from PMR I think.
JSON Turner. I bet you've never heard that one before :D
Or, "JSON Tuner". Jason, sorry for that. :) I like your videos!
haha
9:22 fonts all fit perfectly great new job on videos watching from phone in landscape view and can read it all
On a lark I have been working on a new and improved "rapidxml" utilizing PMR memory resources instead of the implementation of a memory pool that library used. Its a great use case for the monotonic buffer resource. But I am not a developer, I just do it for fun, so I doubt its very good.
PMR is great but the real issue is how data is manipulated.
At work we replaced picojson's strings with properly sized SSO strings, string views where possible, and better hash maps (gosh all of std::map/set are so bad and do tons of allocations per entry) and we earned a factor higher than 10 times faster.
nlohmann's json library is slow because of the same issue, it's designed for correctness, but is using bad containers. Sure, PMR will surely help a bit, but that's like masking the core issue.
Reduce the number of allocations before using PMR.
This is great thanks so much for covering this topic of merging c++ with JSON
5:55 "if you don't know what winking out is your going to have to go to the other episode im not covering that right now" so direct JSON 😆
Really enjoyed the video. I've had a longtime interest in real applications of custom allocation strategies. Finding good teachable examples has always been difficult and are appreciated.
A minor comment for future videos: please turn off the automatic cursor selection blame feature in your editor. I found it to distract from the code itself.
The winking out would be interesting if you could nest memory resources. Bc then you could just wink out subsections of the JSON and reallocate within the same memory resource.
Hi Jason!
1. Have you tried using tcmalloc? How does it compare with PMR? My experience is that tcmalloc is really fast and you do not not the burden of using PMR allocators (in most of the cases?)
2. How does PMR allocators interact with sanitizers and valgrind? As these allocators bypass the standard allocators that valgrind/sanitizers instrument, memory access errors probably cannot be catched and you need to use the new/delete allocator when running with these tools, so probably something like '#ifdef DEBUG #else #endif', and this, everywhere you use these non-default allocators.
1. tcmalloc is good, and will get you some gains, but it can never be as good as a custom tuned strategy provided with PMR.
2. PMR should not interfere with the sanitizers/valgrind at all. They never bypass allocation, they just do larger allocation in blocks. But I haven't done an exhaustive test of that.
Concerning the sanitizers, what I meant is that they are not aware of these allocators. This means for example that valgrind will not be able to catch uninitialized memory reads if that memory was already allocated and then released by the allocator but the underlying memory is still in used by the allocator itself, i.e. it has not been released to the OS. Reads or writes outside of array bounds may also be missed, as well as memory access after free, double free, ....
Concerning tcmalloc, my understanding is that it's basically a thread-safe memory pool, so it should have similar performance as std::pmr::synchronized_pool_resource (and maybe even better as I think it has pools per threads, so synchronization is needed only when releasing memory that was allocated in another thread).
The winking out discussion is actually two episodes ago, #250 starting at about 15:29. This should link to the correct timestamp: ua-cam.com/video/5VrX_EXYIaM/v-deo.html
Can you please make a video on when you use/avoid allocators?
That's a great idea, please add it to the episode tracker: github.com/lefticus/cpp_weekly/issues/
You lost me at " I created my own polymorphic RapidJson allocator adaptor" :)
It would be super cool to test if PMR makes simdjson even faster.
PMR only helps when a library was designed without allocation performance in mind, and it often is shown directly in the API. Returning std::string? Almost always bad.
Simdjson does almost no allocations so it wouldn't win from PMR I think.
simdjson is something to cover as well
One minute in, and I already have to point out simdjson. Now back to watching.
What is the link to the episode which contains - how to create Allocater Aware (AA) types?
ua-cam.com/video/2LAsqp7UrNs/v-deo.html
14:16 589k lost "winking out" 😉
Actually. I'm use simdjson in my projects