3 ms·
> I could get effectively the same performance with containers and move semantics When I’m happy with the level of performance delivered by idiomatic C++ and s
by Const-me 2y ago
> I could get effectively the same performance with containers and move semantics
When I’m happy with the level of performance delivered by idiomatic C++ and standard collections, I tend to avoid C++ all together because I also proficient with C# which is even faster to write and debug.
But sometimes I want more performance. An example from my day job is a multi-step numerical simulation which needs to handle grids of 200M nodes. When processing that amount of data, standard collections are suboptimal. I’m not using std::vector because I don’t need them to grow and I want to allocate these huge buffers bypassing C heap i.e. page-aligned blocks of memory zero initialized by the OS.
- almostgotcaught 2y ago> proficient with C# which is even faster to write and debug. I don't get it - why are we ignoring the fact that C# necessarily implies distributing CLR? NativeAOT doesn't work for everything.
- Const-me 2y agoOn AMD64 Windows, .NET 8.0 runtime takes 31.7 MB to download, and 70.7 MB on disk. On ARM64 Linux, the numbers are 28.4 MB and 75.0 MB, respectively. For that amount of data, both internet bandwidth and disk space are rather cheap these days?
- pjmlp 2y agoAs usual the typical argument that if it doesn't cover 100% of everything it isn't good enough. There are plenty of use cases where NativeAOT works perfectly fine, and is getting better with each .NET release.
- almostgotcaught 2y ago> As usual the typical argument that if it doesn't cover 100% of everything it isn't good enough. This text > When I’m happy with the level of performance delivered by idiomatic C++ and standard collections, I tend to avoid C++ all together because I also proficient with C# which is even faster to write and debug. very strongly implies that they're completely interchangeable. They're not. It's as simple as that. Sometimes it's hard to keep track of whether I work in software or politics.
- neonsunset 2y ago> very strongly implies that they're completely interchangeable Not completely but they are interchangeable. C# at its inception was as much inspired by C++ as it was by Java. Since then, it only further evolved to accommodate far more low-level scenarios and improve their performance. It provides the kind of capabilities you'd usually expect from C++, so this statement holds true. Calling C exports is one `static extern ...` method away, you can define explicit layout for structs (that satisfy 'unmanaged' constraint), you have fixed arrays in structs, stack buffers, pointers and ability to do raw or abstracted away manual memory management, etc. You can mmap device-shared memory and push data into GPU. You can accept pointers from C or C++ and wrap them into Span<T>s and pass those to most standard library methods.
- almostgotcaught 2y ago> Not completely but they are interchangeable ... <whole lotta words telling me things i'm already extremely well aware of> I'll just ask you this extremely simple question: does C# compile/run/whatever-magic-you-think-it-does on targets that aren't in {x32, x86, ARM64}? Does it target RISC-V? Does it target PTX? Does it target AMDGPU? Are you getting the picture? Pre-empting the most low-brow dismissal: these are only niche targets if you've never heard of a company called NVIDIA.
- Const-me 2y ago> on targets that aren't in {x32, x86, ARM64}? I have personally shipped embedded Linux software running on 32 bit ARMv7 SoC written mostly in C#. The product is long in production and we’re happy with the outcome. > Does it target RISC-V? Not sure if it’s ready for production, but see that article: https://www.phoronix.com/news/Microsoft-dotNET-RISC-V https://www.phoronix.com/news/Microsoft-dotNET-RISC-V > Does it target PTX? According to nVidia, the answer is yes: https://developer.nvidia.com/blog/hybridizer-csharp/ https://developer.nvidia.com/blog/hybridizer-csharp/ > Does it target AMDGPU? Not sure, probably not.
- 2y ago
- jltsiren 2y agoI've been using std::vector with arrays that take up to tens of gigabytes for ~15 years without any real issues. Once the size of the allocation exceeds a few megabytes, any reasonable allocator is going to use an anonymous memory map anyway. And if the array doesn't need to grow, it takes effort to make a standard library vector worse than a manually optimized one. It's just a pointer and two integers, after all.
- Const-me 2y ago> it takes effort to make a standard library vector worse than a manually optimized one A simple use case is a 2D array where rows are padded to be multiples of 32 bytes (size of AVX SIMD vectors, saves a lot of implementation complexity because no need to handle remainders) or 64 bytes (saves a tiny bit of performance when parallelizing, guarantees cache lines aren’t shared between rows). When element size is not a power of 2, it’s impossible to implement that RAM layout on top of an std::vector
- jltsiren 2y agoIt's obviously possible to find niche cases where the standard containers are not good enough. But the remaining 9999 cases out of 10000 are more interesting. I also had one of those, in an application that created and deleted a large number of fixed-size arrays across many threads. A naive implementation using glibc malloc ended up with a massive memory leak caused by hundreds/thousands of fragmented arenas. A thread could usually not reuse the memory it had just freed, because it was using a different arena. And because the arena was not empty, it was not possible to unmap the memory.