15 ms·
The Windows malloc() implementation from MSVCRT is slow
- rayiner 4y agoI wonder how much of this is the development culture at MS. https://www.theregister.com/2022/05/10/jeffrey_snover_said_microsoft_demoted/ https://www.theregister.com/2022/05/10/jeffrey_snover_said_m... (“When I was doing the prototype for what became PowerShell, a friend cautioned me saying that was the sort of thing that got people fired.”) In that environment I can imagine nobody wants to be on the hook for messing with something fundamental like malloc(). The complete trash fire that is O365 and Teams—for some reason the new Outlook kicks you out to a web app just to manage your todos—suggests to me that Microsoft may be suffering from a development culture that’s more focused on people protecting fiefdoms than delivering the best product. I saw this with Nortel before it went under. It was so sclerotic that they would outsource software development for their own products to third party development shops because there was too much internal politics to execute them in house.
- munch117 4y agoYou shouldn't read too much into the PowerShell story. Creating your own programming language is in most cases a frivolous vanity project. Spending company resources on your own frivolous vanity projects is the sort of thing that can get you fired.
- sterlind 4y ago! I disagree. CMD badly needed replacing. MS needed a new shell language. A functional company would connect people with a passion for X with the resources to achieve X, if X has a chance of helping the company. Windows Terminal and WSL show how far MS has come from the PS days. (Disclaimer: I work for MS)
- londons_explore 4y agoI think the smart move would have been to make an official port of bash...
- hughw 4y agoMaybe that's how we got WSL
- jrockway 4y agoSome experimentation in that space is probably a good thing. Bash is familiar, but it's far from perfect. In terms of executing programs, it gets the critical functionality down pretty well; readline-based editing, variables, aliases, pipes, IO redirects, background process management, etc. In terms of being a programming language, I always regret when I use it. I recently had a minor heart attack when I realized that our CI was green when tests were failing; deep down in some shell script, someone forgot to turn on "pipefail" and the shell linter to check for that was misconfigured, and so the CI command that piped output to a logfile failed, but the log file was written OK, so "exit 0". In terms of interactive poking around at a computer, I never really liked the UNIX philosophy here. I run a terminal emulator, which connects to a remote server over SSH, which is running a terminal multiplexer, which is running bash, which then runs my programs. None of these things know anything about each other. The UNIX way!!! The end result is total jank and some useful features are completely impossible to implement. The various shells running under the multiplexer overwrite each other's history. The terminal multiplexer can't give the terminal emulator its scrollback buffer. The shell history is specific to the machine that the shell is running on, not the machine that the terminal is running on. Echoing the character you just typed involves two TCP round trips! It's so bad, guys. For that reason, I totally see the desire to re-engineer this space. There are a lot of improvements to be mad. Powershell is an interesting attempt. It doesn't solve any of my problems, though, and I personally don't enjoy using it. It's verbose and unergonomic, and still not a good programming language for making stuff happen. Windows is missing the glue ecosystem of things like "grep", "sed", "curl", etc., which make matters worse. (Powershell provides some of those things as cmdlets, but the "curl" one opens up IE to make you click something, and weird stuff like that.) It's nice that someone tried to make a new thing. I personally think it's worse than everything else out there. TL;DR: "we've always used bash" leaves a lot to be desired. It's fine. But if someone says they can do better, I completely agree.
- 13of40 4y agoThe way I remember it, the need for a new shell language for system administration was something that lots of people in Windows Server were trying to solve. Ballmer talked about it, we had a push to add a handful of new command line tools (like tasklist.exe I think) that you could use under CMD, and there was a proof of concept where MMC could be used to output some kind of macro language when users did things in the UI. PowerShell was the thing that eventually won, and I think it was largely because it stood on the shoulders of .Net so had a ton of capability right out of the gate. (And TBH, I think it's a little bit weird that we have this mythos today where Snover sat down at his computer one morning and invented it out of thin air, when even the v1 feature team had something like 30 engineers and PMs on it.)
- skissane 4y ago> CMD badly needed replacing CMD is nasty but there are lots of little ways in which it could have been improved. For example, provide an option to disable that useless "Terminate batch job (Y/N)?" prompt. I wish Microsoft would open-source CMD.EXE. I dislike how slow PowerShell is (especially its startup). Maybe nobody at Microsoft cares about CMD.EXE enough to fix those long-standing little annoyances like the above, but if it was open-source other people out there would. Also, I wonder why nobody ever seemed to have thought of integrating CSCRIPT into CMD, so that you could have seamlessly mixed VBScript (or other WSH languages) into batch files.
- munch117 4y agoI didn't say that this project in particular was a vanity project. Just that when someone comes to you with a project and says "I'm going to solve our problems by using this new programming language that I'm in the process of inventing", then some skepticism is not unwarranted. In hindsight, this particular one may be the best thing since sliced bread. But that's survivorship bias.
- sterlind 4y ago(I work for MS, though in core Azure rather than Office or Windows.) I think that PowerShell story was how old MS worked, back in the days of stack ranking, hatred of Linux and the Longhorn fiasco. things inside the company are a lot more functional now. I saw internal politics drama at my first position, but once I moved everything was chill, and experimentation and contributing across team boundaries was actively encouraged and rewarded. I suspect Office suffers from a ton of technical debt, along with being architecturally amorphous and dating from a pre-cloud era. as for Windows, the amount of breakage I see in the betas suggests they're not afraid of making deep changes, it's probably that MSVCRT is a living fossil and has to support old programs monkeypatching the guts of malloc or something.
- lkfjasdlkjfsad 4y agoany idea what the hell is going on with Teams? why can't i simply scroll up in my own conversations? let alone search them. the sticky sludge of communication in something as simple as chat has cost me hours since i was forced to use teams. outlook search is so superior to teams i'd easily prefer to have lync back. this one thing absolutely cripples communication. there are a list of other very basic issues that make communicating code blocks frustrating. i see new app features here and there, i saw some feature added the other day which won't help anyone. i just don't understand the prioritization of issues i don't expect a direct answer to this, although i hope to read an explanation one day EDIT: i removed content from this comment that was missing the point
- stagger87 4y agoPEBKAC, you can scroll and search chats in teams.
- lkfjasdlkjfsad 4y ago> you can scroll outrageously slowly, and i'm not talking about a couple HTTP requests and a database query slow > and search search is not practical in my opinion. i'd go as far as saying it's unusable. i can _find individual messages_, but there are times (often, i might add!) where context or jumping to that message aren't even options. context is often the reason you search for messages in the first place. if i'm alone here, sure, PEBKAC
- assttoasstmgr 4y ago> people protecting fiefdoms than delivering the best product. Apparently you have never worked at any company with more than 50 employees because that's literally how every large company works. Career-obsessed managers who can't see the forest for the trees not giving a single shit about the overall product as long as their goals were met. They're off to the next promotion before all hell breaks loose.
- DHowett 4y agoI'm curious whether the "new"(ish) segment heap would address some of the author's issues. It's poorly documented, so I can't find a reference explaining what it is on MSDN save for a snippet on the page about the app manifests[1]. There's some better third-party "documentation"[2] that gets into some specifics of how it works, but even that is light on the real-world operational details that would be helpful here. Chrome tried it out and found[3] it to be less than suitable due to its increased CPU cost, which might presage what Erik would see if they enabled it. [1] https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests#heaptype https://docs.microsoft.com/en-us/windows/win32/sbscs/applica... [2] (PDF warning) https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Windows-10-Segment-Heap-Internals.pdf https://www.blackhat.com/docs/us-16/materials/us-16-Yason-Wi... [3] https://bugs.chromium.org/p/chromium/issues/detail?id=1102281 https://bugs.chromium.org/p/chromium/issues/detail?id=110228...
- MarkSweep 4y agoThe one other piece of “documentation” that I know of is this blog post: https://blogs.windows.com/windowsexperience/2020/05/27/whats-new-in-the-windows-10-may-2020-update/ https://blogs.windows.com/windowsexperience/2020/05/27/whats... It mentions that the segment heap is used by default for UWP apps and reduces memory usage of Edge.
- chrisseaton 4y agoSo why is it a trash fire? It's just slow? Or is there something else wrong with it? I thought the author was going to say it did something insane or was buggy somehow.
- deleted 4y ago[deleted]
- Someone 4y agoAlso, is it slow because it’s badly implemented, or is it better than other mallocs in some other respect? Maybe, dating from decades ago, it’s better in the memory usage front?
- KerrAvon 4y agoHas everyone forgotten that Unix is the common ancestor of Linux and every other Unixlike? I’m seeing an uptick of people writing nonsensical comments like “this was written for Linux (or Mac OS X, which implements POSIX and is therefore really Linux in drag)”.
- copperx 4y agoApparently yes, because all I ever hear is "macOS is like Linux" and even "macOS is really Linux behind the scenes" from less enlightened people.
- jchw 4y agoNo... That's why they had the parenthetical. The problem is, your computer probably doesn't boot the common ancestor. If you're writing UNIX-like stuff, most likely it boots macOS or Linux. If you're cool maybe it's one of the other modern BSD variants aside macOS. In practice there's a pretty low probability that your code also runs on all POSIX-compliant operating systems, and more honest/experienced people often don't kid themselves into thinking that they're seriously targeting that. Even if you believe it, you probably have some dependency somewhere that doesn't care, like Qt for example. Saying something like "Linux (or macOS, which is similar)" is a realization that you're significantly more likely to be targeting both Linux and macOS than you are to even test on BSD. And to solidify that point, note that lots of modern CI platforms don't even have great BSD support to begin with. Of course, there is a semantic point here. macOS nominally really is UNIX, except for when someone finds out it's not actually POSIX compliant due to a bug somewhere every year or so. Still, it IS UNIX. But what people mostly run with that capability, is stuff that mostly targets Linux. So... yeah. Of course it is true that some people really think macOS is actually Linux, but that misunderstanding is quite old by this point. addendum: I feel like I haven't really done a good job putting my point across. What I'm really saying is, I believe most developers targeting macOS or Linux today only care about POSIX or UNIX insofar as they result in similarities between macOS and Linux. That macOS is truly UNIX makes little difference; if it happened to differ in some way, developers would happily adjust to handle it, just like they do for Linux which definitely isn't UNIX.
- naniwaduni 4y ago
- Sesse__ 4y agoJust wait until you try to use it from multiple threads at the same time!
- eps 4y agoNot sure what's your usage was exactly, but Heap API works reallly well in this context. So much so that beating it with a custom allocator is a real challenge.
- Sesse__ 4y agoI had a system that was sped up by 30%+ on Windows by switching from HeapAlloc to jemalloc. Profiling showed that HeapAlloc was largly stuck in a single giant lock. (This was on Windows Server 2016, IIRC.) And that wasn't even that allocation-heavy in the large scale of it; most of memory was done through arena allocations, but a few larger buffers were not.
- TonyTrapp 4y agoNot that it helps here, but Microsoft never considered the MSVCRT that ships with Windows to be public API. This is not the "Windows allocator", this is the (very) old MSVC runtime library's allocator. Of course that doesn't keep anyone from using this library because it's present on any Windows system, unlike the newer MSVC versions' runtime library. Using the allocator from a later MSVC's runtime library would provide much better results, as would writing a custom allocator on top of Windows' heap implementation. MSVCRT basically just exists for backwards compatibility. It's impossible to improve this library at this point.
- jart 4y agoIt's effectively mandatory. Microsoft provides about twelve different C Runtimes. But if you're building something like an open source library, you can't link two different C runtimes where you might accidentally malloc() memory with one and then free() with the other. If you want to be able to pass pointers around your dynamic link libraries, you have to link the one C runtime everyone else uses, which is MSVCRT. Also worth mentioning that on Windows 10 last time I checked ADVAPI32 links MSVCRT. So it's pretty much impossible to not link.
- TonyTrapp 4y agoIt isn't mandatory. I have never actively linked against MSVCRT on Windows. From my experience it's mostly software that isn't built with Visual Studio that uses MSVCRT, or software that that takes extreme care of its binary size (e.g. 64k intros). MSVCRT is not even an up-to-date C runtime library. You wouldn't be able to use it for writing software requiring C11 library features without implementing them somewhere on top of it. It's true that you cannot just happily pass pointers around and expect someone else to be able to safely delete your pointer - but that is why any serious library with a C interface provides its own function to free objects you obtained from the library. Saying that this is impossible without MSVCRT implies that every software needs to be built with it, which is not even remotely the case. If I wanted, I could build all the C libraries I use with LLVM and still link against them in my application compiled with the latest MSVC runtime or UCRT. The much bigger problem is mixing C++ runtimes in the same piece of software, there you effectively must guarantee that each library uses the same runtime, or chaos ensues.
- somerando7 4y ago> I was taught that to allocate memory was to summon death itself to ruin your performance. A single call to malloc() during any frame is likely to render your game unplayable. Any sort of allocations that needed to happen with any regularity required writing a custom, purpose-built allocator, usually either a fixed-size block allocator using a freelist, or a greedy allocator freed after the level ended. Where do people get their opinions from? It seems like opinions now spread like memes - someone you respect/has done something in the world says it, you repeat it without verifying any of their points. It seems like gamedev has the highest "C++ bad and we should all program in C" commmunity out there. If you want a good malloc impl just use tcmalloc or jemalloc and be done with it
- TonyTrapp 4y agoAs always there is some truth to it - the problem of the MSVCRT malloc described in this blog article is the living proof of that - but these days it's definitely not a rule that will be true in 100% of cases. Modern allocators are really fast.
- forrestthewoods 4y agoStrong agree. I recently wrote a semi-popular blog post about this. https://www.forrestthewoods.com/blog/benchmarking-malloc-with-doom3/ https://www.forrestthewoods.com/blog/benchmarking-malloc-wit... It's interesting that LLVM is suffering so horrifically using default malloc. I really wish the author did a deeper investigation into why exactly.
- dang 4y agoDiscussed here: Benchmarking Malloc with Doom 3 - https://news.ycombinator.com/item?id=31631352 https://news.ycombinator.com/item?id=31631352 - June 2022 (30 comments)
- charles_kaw 4y agoIf this person was taught game dev any time before about 2005, that would have still been relevant knowledge. Doing a large malloc or causing paging could have slaughtered game execution, especially during streaming. >If you want a good malloc impl just use tcmalloc or jemalloc and be done with it This wasn't applicable until relatively recently.
- softwaredoug 4y agoMy knowledge is like 10 years old - For a long time, Microsoft's stl implementation was based on their licensning of dinkumware's STL (https://www.dinkumware.com/ https://www.dinkumware.com/). Not something maintained in house. It seemed to work OK'ish - giving lowest common denominator functionality. However, it was pretty easy to create higher performing specialized data structures for your use case then what seemed like simple uses of dinkumware STL.
- garaetjjte 4y agomalloc is not related to STL. But about it, big issue with Microsoft STL is that it is atrociously slow on debug builds.
- oddity 4y agoIf you're depending on the performance of malloc, you're either using the language incorrectly or using the wrong language. There is no such thing as a general purpose anything when you care about performance, there's only good enough. If you are 1) determined to stick with malloc and 2) want something predictable and better, then you are necessarily on the market for one of the alternatives to the system malloc anyway.
- mwcampbell 4y agoThe whole point of the article, though, was that the system malloc was good enough on Linux and Darwin.
- oddity 4y agoThis misses the point of my comment. When you put faith in malloc, you're putting hope in a lot of heuristics that may or may not degenerate for your particular workload. Windows is an outlier with how bad it is, but that should largely be irrelevant because the code should have already been insulated from the system allocator anyway. An over-dependence on malloc is one of the first places I look when optimizing old C++ codebases, even on Linux and Darwin. Degradation on Linux + macOS is still there, but more insidious because the default is so good that simple apps don't see it.
- dzaima 4y agoExcept that I'd guess that there is no "good" case in the case for MSVCRT's malloc. You shouldn't assume malloc is free, but you should also be able to assume it won't be horrifyingly slow. Just as much as you should be able to rely on "x*y" not compiling to an addition loop over 0..y (which might indeed be very fast when y is 0). Yes, this unfortunately isn't the reality MSVCRT is in, but it is quite a reasonable expectation.
- oddity 4y agoIt's unreasonable to assume that an stdlib must be designed around performance to any capacity. For most software, the priorities for the stdlib are 1) existing, 2) being bug/vulnerability free, and likely, in the Windows case given Microsoft's tradition, 3) being functionally identical to the version they shipped originally. Linux and macOS have much more flexibility to choose a different set of priorities (the former, through ecosystem competition and the latter through a willingness to break applications and a dependence on malloc for objc), so it's not at all a fair comparison. The fact that malloc doesn't return null all the time is a miracle enough for many embedded platforms, for example, so it's not exclusively a Windows concern. Environments emphasizing security in particular might be even slower. Multiplication is not a great argument... There's a long history of hardware that doesn't have multipliers. Would I complain about that hardware being bad? No, because I'd take a step back and ask what their priorities were and accept that different hardware has different priorities so I should be prepared to not depend on them. Same thing with standard libraries. You can't always assume the default allocator smiles kindly on your application.
- moonchild 4y ago> it basically represents control flow as a gigantic DAG Control flow is not a DAG.
- 3836293648 4y agoPretty sure they mean the AST is a DAG
- pshirshov 4y agoWell, why?
- AshamedCaptain 4y agoDirected _Acyclic_ Graph. Control flow graph has loops.
- pshirshov 4y agoThis guy builds a compiler. I guess he added some limitations into his model so his CF can be represented as a DAG. I have a compiler which represents its CF as a DAG.
- tick_tock_tick 4y agoFor it to be a DAG you'd have the solve the halting program wouldn't you?
- remram 4y agoNo. Knowing whether programs end in finite time (dependent on input) doesn't mean all programs end or that all programs end in constant time. The halting problem is also not considered unsolved (though P=NP is unsolved).
- spatulon 4y agoYou're not wrong. I guess they're just trying to say that LLVM's control-flow graph is implemented as individually heap-allocated objects for nodes, and pointers for edges. (I haven't looked at the LLVM code, but that sounds plausible). Even if those allocations are fast on Linux/Mac, I wonder whether there are other downsides of that representation, for example in terms of performance issues from cache misses when walking the graph. Could you do better, e.g. with a bump allocator instead of malloc? But who knows, maybe graph algorithms are just inherently cache-unfriendly, no matter the representation.
- bjourne 4y agoWell... Who told you to link to MSVCRT (the one in System32)? Not Microsoft that's for sure. New software is supposed to link to the Visual Studio C runtime it was compiled with and then ship that library alongside the application itself. Even if you don't compile with VS you can distribute the runtime library (freely downloadable from some page on microsoft.com). Ostensibly, that library contains an efficient malloc. If you willingly link to the MSVCRT Microsoft for over a decade has stated is deprecated and should be avoided you are shooting yourself in the foot. "Windows is not a Microsoft Visual C/C++ Run-Time delivery channel" https://devblogs.microsoft.com/oldnewthing/20140411-00/ https://devblogs.microsoft.com/oldnewthing/20140411-00/
- spatulon 4y agoI suspect they are actually talking about the modern/redistributable C/C++ runtime, not the old msvcrt.dll. Microsoft refer to the modern libraries as the "Microsoft C and C++ (MSVC) runtime libraries", so shortening that to MSVCRT doesn't seem unreasonable.
- sterlind 4y agothere's a weird licensing thing for the VC runtime where you can't redistribute the dll alongside your code unless you have a special license. instead, you have to install it as an MSI. I have no idea why they created that restriction. I even work for MS and it baffles me.
- londons_explore 4y agoAt one point MS was very keen for people to use MSI's rather than building custom installers that jam things into system32. Perhaps that was why.
- Dylan16807 4y agoBut if you're using it for yourself you wouldn't want to put it in system32.
- bcbrown 4y agoSeeing someone refer to any piece of software technology as a "trash fire" makes it harder for me to view them as credible. It's unnecessarily divisive and insulting, and it means it's unlikely they will have any appreciation of the tradeoffs present during initial design and implementation.
- dang 4y agoWe've replaced the baity wording with more representative language from the article, in keeping with the HN guideline: "Please use the original title, unless it is misleading or linkbait; don't editorialize." https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- deleted 4y ago[deleted]
- barrkel 4y agoWindows doesn't have a malloc. The API isn't libc like conventional Unix and shared libraries on Windows don't generally expect to be able to mutually allocate one another's memory. Msvcrt as shipped is effectively a compatibility library and a dependency for people who want to ship a small exe.
- qsdf38100 4y agoNote that Windows has HeapAlloc and HeapFree, which provide all the functionality to trivially implement malloc and free. The C runtime is doing exactly that, except it adds a bit of bookkeeping on top of it IIRC. And in debug builds it adds support for tracking allocations.
- barrkel 4y agoVirtualAlloc is a better base for a custom memory allocator. It's closer to mmap + mprotect in functionality. There's also CoTaskMemAlloc (aka IMalloc::Alloc). And COM automation has a bunch of methods which allocate memory for dynamically sized data, which could be abused for memory allocation - SafeArrayCreate, SysAllocString.
- astrange 4y agoIt sounds like they've invented 15 different ways to allocate memory rather than have malloc. What did they do that for? (Not to say malloc is a perfect API, it’s definitely oversimplified, but they probably didn’t solve any of its problems.)
- barrkel 4y agoThe latter three are for RPC / interop / automation scenarios, simplifying the programming model for things like Visual Basic. HeapAlloc (and legacy routines GlobalAlloc and LocalAlloc which wrap it) is mostly a relic of 16-bit Windows. VirtualAlloc is the one that matters for language runtimes on Windows since Win32 API in the 90s, and it's designed to allocate slabs which are suballocated by more sophisticated code.
- pjmlp 4y agoThere is no Windows malloc(). Only UNIXes have the C API as part of the OS API.
- jart 4y agomalloc() isn't part of the Linux API which provides mmap().
- pjmlp 4y agoSince we are getting pedantic, Linux isn't a UNIX.
- jart 4y agoI thought it was. Some distro (I forget the name) paid to be certified with The Open Group.
- CyberDildonics 4y agoIt's absurd you would call someone pedantic for saying malloc is in a library on linux after trying to say that malloc in a library on windows.
- pjmlp 4y ago
- CyberDildonics 4y agoWhy are you calling me your "dear". Don't ever talk to me that way again.
- chrisseaton 4y ago> Linux isn't a UNIX I think this isn't quite right - I think some distributions are actually certified as UNIX. https://www.opengroup.org/openbrand/register/ https://www.opengroup.org/openbrand/register/
- fguerraz 4y ago"Don't use spinlocks in user-land."
- eska 4y agoHe only did as a workaround for a performance issue in the mutex.
- evmar 4y agoThe other inaccuracies in this article have already been covered. I noticed there was also a weird rant about mimalloc in there ("For some insane reason, mimalloc is not shipped in Visual Studio"). My understanding is mimalloc is basically a one-person project[1] from an MSR researcher in support of his research programming languages. It sounds like it's pretty nice, but I also wouldn't expect it to be somehow pushed as the default choice for Windows allocators. [1]: https://github.com/microsoft/mimalloc/graphs/contributors https://github.com/microsoft/mimalloc/graphs/contributors
- denkshom 4y agoThis rant was rather devoid of relevant technical detail. I mean, why exactly is the malloc of the compatibility msvcrt so slow compared to newer allocators? What is it doing? An analysis of that would have been some actual content of interest.
- shaggie76 4y agoI wonder if he was running with the debugger attached; we also saw atrocious performance with MSVCRT malloc until we set _NO_DEBUG_HEAP=1 in our environment.
- trollied 4y agoThe Factorio team were looking at a performance bug recently & tracked it down to similar: https://forums.factorio.com/viewtopic.php?f=7&t=102388 https://forums.factorio.com/viewtopic.php?f=7&t=102388 https://developercommunity.visualstudio.com/t/mallocfree-dramatic-performance-slowdown/552439 https://developercommunity.visualstudio.com/t/mallocfree-dra...
- eska 4y agoSo Microsoft changed the malloc behavior for UWP apps, but not desktop apps. In other words they saw it as problematic enough to change it but then say it’s not a bug for the other case. Schizophrenic.
- InfiniteRand 4y agoThe thread on the second link gives some clue as to why things are the way they are