I'd quibble with whether folks understand the performance implications. I think most people know division is expensive. It's just non trivial to remove it. If it was that easy to replace, it would be done in hardware and division wouldn't be expensive anymore.
I think the problem is equating "coding" to "algorithmic thinking."
Most coding problems are wiring stuff up. If you can change a tire or put together a LEGO set, you can probably write code.
The problem with the golden geese that you're pointing out is mostly one of tooling, in my opinion. Undergrads at top CS programs are as clueless as your grandmother about developing software because the tools are either toys for children or extremely sharp knives with a blade on the handle. This is a problem that replit is trying to solve.
I wish spreadsheets had better support for version control and automated regression testing. Tons of people can program, and they'd all be well-served by such tools.
Efficient 3 dimensional position or range queries (line/column/page) is a pretty well studied problem. You don't need to query every point of the space to answer anything.
It's a task more commonly found in computational geometry (3D range query == find all the points in a data set enclosed by a cube).
There are numerous data structures that are well suited for various geometric queries like ranges/lookups (interval trees, quadtrees) as well as more text-oriented operations like cut/copy/paste/insert/merge/etc (like ropes).
I'm not familiar with the operations required to put a cursor at the right place in a document, but knowing how much research has gone into storing similar data and looking up what you need efficiently the idea of "going through all the text every time" is a big code smell.
Microsoft Word, Pages and Open Office don't seem to be bottlenecked by rendering performance like Google Docs. Perhaps the browser is the wrong platform for document editing.
I believe this 100%. After using google office for years (just because it's free and cloud-based), I recently tried MS Word and Excel recently at work. The different was mind-blowing. I forgot just how functional and straightforward MS Office is compared to the clunky, barebones google options.
If I wanted a desktop-first, cloud-backed solution, what would be the most future-proof and durable? Can I use Open Office across OSes? What would be the best cloud backup service these days? (just a general question to readers)
I also prefer desktop-first, cloud-backed solutions, but I have quite the opposite experience. Working with MS Office has been a pain and I've been a happy Google Docs user for about 10 years. My wife who isn't an especially technical person also finds Google Docs quite a lot more intuitive and laments when she has to use MS Office products for work (she is a consultant for Microsoft including their 365 line of business and her whole firm makes pitch decks in Google Slides before converting them to MS Office to present at Microsoft meetings--IIRC for the Azure and other b2b lines of business they don't even bother with MS Office). Note that my wife and I (like most of our age group) grew up on MS office, so it's not a question of familiarity.
Google Docs just built a better product and MS Office still hasn't caught up. I wonder if this is because or in spite of the browser target?
Google Docs seems so bare-bones. I recently couldn't find a way to format a series of chunks of text within a Google Doc as code, and I'm pretty sure that it simply doesn't support styles for anything but headings and body text. It just doesn't seem to be the same kind of tool as Word.
Copy a few cells from a Google sheet and paste it in an email, then do the same with Excel. Collaborate on building out a document from scratch with 10 people in Google sheets vs Excel.
Excel is a monster, and much more powerful than Google sheets in many ways, but in my experience, Google docs apps are a little better for collaboration, and they integrate a little tighter with each other.
Google docs is their document editor. Sheets is a part of GSuite.
I've also never had trouble pasting a spreedsheet selection into a word document. Email is a nightmare in general though.
I'm not sold on collaboration personally. I've had to do it a bunch since the pandemic began and I've found it to be an anti pattern. One of the big inconsistencies is that cells in sheets don't update while being edited while collaborating, which is not great if you have a spreadsheet heavy workflow. Docs is impossible to replace that though, because it's auto formatting is draconian and always seems to reset its preferences. When editing docs we spend more time formatting them then creating the content.
> I'm not sold on collaboration personally. I've had to do it a bunch since the pandemic began and I've found it to be an anti pattern.
How much of this is really related to technology? I do a lot of writing in both Word and Google Docs and see different sets of problems for both products. Having a group of people jump into either and expecting a good product (and experience getting there) is unrealistic.
With the pandemic, I think people have been trying lots of things without understanding what will be most effective. At least early on, there was a feeling that people had to be seen to be productive. It's nothing like real remote work.
For important docs, I still come back to having individuals write their content and only then does one person attempt to assemble it. The individuals often need their own independent reviews and consultation anyway before they have a decent draft. In some ways it improves visibility and helps with keeping folks on schedule too.
Google sheets is the specific example that I hate. In my experience, it's often laggy and clunky. You can't even scroll smoothly: the window MUST snap to row/column lines. When I realized that google sheets has such a laughable shortcoming, I knew I needed to get out of google office eventually.
i think copying some cells from excel into outlook, which i guess is the comparable transaction, works pretty well - what doesn't work for you? Maybe I am just missing out on some amazing functionality by not using google docs.
Personally, I like it better sometimes for having less features. MS Word has such a massive number of formatting features that interact in complex ways that there's plenty of ways for your document to end up formatted in a weird way and to be very difficult to figure out exactly where the switch is to make it not do something. I think one time I had a document where the entire doc was highlighted in yellow, and it took me over an hour of fiddling with various formatting boxes to figure out how to turn it off. Any word processor that doesn't have the capability to do that has some appeal to me.
I haven't seen a word processing document in a professional setting for many years now (didn't realize it until just now). Who uses a word processor these days? Writers certainly don't use that garbage.
I use text editors so I can think about the content and if it is going to get prettied up with fonts it goes into a target system that supports markdown (confluence, git, email, etc..). If you are flummoxing around in a word processor or sending around formatted docs that aren't PDF I fully expect people to be looking at you sideways.
I hate to inform you that, yes, writers do indeed use “that garbage”. I’m married to an author who regularly uses Scrivener to write. But anytime she has to send anything to anyone she has to convert to a Word document and send that out. Everyone uses Word that she interacts with. (Though author friends of hers might also use Scrivener for their writing)
Writers who understand git, let alone Markdown, are going to be extremely rare. You’re in a bubble if you haven’t encountered how dependent the writing field is on Word documents.
Unfortunately I do agree with this. I think a lot of tech isn't a matter of "what's the best?" but instead "what's the least bad?". I don't think Office is perfect but I think it's a lot less bad than google. I don't think MacOS is great but it's a lot better than windows for certain things, and vice versa. IMO unless software puts the user first in allowing customization and control, the best we can ever get is good instead of great.
I would recommend Libreoffice over Openoffice, but yes (for both)
And you can of course backup to your cloud service of choice. The main benefit of google docs, o365, etc. Is real-time collaboration. But there is no reason why a desktop app couldn't support realtime collaboration with a suitable backend service.
The only time I've ever seen real-time Google Docs collaboration has been during meetings which should have been an email. Total waste of everyone's time. Not to mention the horrible UX of people constantly moving their cursor around and moving text around. I'd suggest that pass-the-baton style collaboration would be a much better UX if you absolutely must collaborate real-time on creating a document. Which I find the premise to be incredibly dubious to begin with.
Even if actual realtime collaboration is rare, there are other collaboration features that are missing in most desktop equivalents, like getting notified of changes, being able to mention people in comments, etc. that I do see used quite a bit.
But my experience is that realtime collaboration is useful. In particular, immediately after emailing a doc to multiple people it is not at all unusual for more than one person to be actively looking at commenting on, and maybe changing the document at the same time.
I have had the exact opposite experience—I've used Google Docs for 10 years now, and in every way it manages to exceed Microsoft Office in usability. You're right that Google Docs can sometimes feel a little barebones, but it makes up for it by being very easy and straight-forward to use. In 10 years of using Google Docs, I can count on one hand—across probably tens of thousands of documents—the amount of times I've been missing something so critical to my work that I've needed to use an Office product.
(That said, I'm really excited about the recent changes Microsoft is making for Excel, with LET and LAMBDA, and I look forward to trying it out again in the future. Maybe this is the thing that finally gets me to switch! I've also enjoyed doing some more ~fancy~ graphic design in Pages on Mac, but overall the clunkiness was just so frustrating that I can't in good faith recommend it to anyone)
I prefer LibreOffice over Open Office, but I believe both are cross-platform (Linux, Windows, macOS). Then, I'd just use Dropbox or similar to save the files to for cloud storage. The only downside is no real-time collaboration. You can also look into Collabora, but I don't have any experience with it.
If you don't require Linux support or if the web is tolerable for Linux, I personally recommend the Microsoft Office suite. There's the obvious compatibility concern because nearly everyone uses those, they have real-time collaboration built in for both desktop and the web, comes with OneDrive storage, and will obviously be extremely future-proof. I cannot recall a single time any of the apps have crashed on me on both Windows and macOS, so I think it's pretty "durable".
IMHO HTML documents backed by a versioning system (probably fossil or pijul rather than the overly complex git) are the way forward for documents where content is much more important than presentation.
While “text in a VCS” is a great option, it’s obviously far less usable than something like Google Docs, and you still don’t get real-time collaboration, which can be really nice.
Yeah... I'm wondering though, Fossil is based on SQLite - a database - and databases are designed to solve the issues arising when multiple users try to change the same data. (Also, fossil by default works in "autosync" mode.) So it should be "easy(er)" to make a real-time collaboration tool based on Fossil ?
P.S.: By researching this, I've stumbled on a (barebones) alternative to Google Docs : HackMD/CodiMD/HedgeDoc :
https://demo.hedgedoc.org/
The best approach for a desktop first cloud-backed solution is possibly to have a VDI with Windows (on AWS for example), and use Microsoft Remote Desktop from your preferred physical computer to access it.
I have multiple desktop Macs in my various homes but I only use them for web browsing and RDP to the same Windows VDI.
A free OneDrive account is enough, plus Office 2016+
autosave function, with the added bonus to have a cloud version of word to edit in collaboration your document on the go
It was indeed a very strong marketing move for... decades to convince people, like smart people, that document editing can be a web-based thing. Actually, now that the browser is so ubiquitous that GUIs sit on top of it (think Electron), then is time to ask the very obvious question - since everyone seems to agree that universal GUI is needed (proof: the browser) then is the browser the right universal GUI?
Not being heavily biased by any vendor, but really, is there anything better than XAML to describe user interfaces, that is also cross-platform and does not have the burden of DOM? Please - share examples.
Absolutely not; but the web has became the behemoth it is through an absurd amount of money and engineering work. Chrome (well, Chromium) has 34 million lines of code now[1].
If we assume any competing universal GUI platform will need a similar amount of engineering effort, there's a very small list of companies in the world who have the resources to fund an effort like that. And Apple, Microsoft and Facebook have very little strategic incentive to care. (React Native notwithstanding). Google is trying with Flutter - but we'll see.
I wonder if maybe the the right direction is up. WASM is already supported by all major browser engines. I'd love to see a lower level layout & rendering API for the browser, exposed to wasm. We could do to the DOM what Vulcan did to OpenGL. And like opengl, if it was designed right, you should be able to reimplement the DOM on top in (native wasm) library code.
Then the universal GUI of the future could be the gutted out shell of a web browser (we'd just need wasm + the low level layout engine), running libraries for whatever UI framework you want to use, written in any language you like. A UI environment like that would be small, portable and fast.
That smells suspiciously like the Linux desktop environment. There was X. It was a minimal desktop environment. Then there were dozens of ones built on that… there was almost no way to have a consistent experience for a really, really long time.
Yeah, but the web isn’t very consistent already. The main set of common elements are buttons, links, form elements and scroll bars. Just about everything else is done custom on every webpage you visit.
I don’t think we should get rid of the common UI elements (if anything we need more of them & better APIs for them). But what Google docs, and flutter seem to really want is a simpler, more primitive way to create a layout out of those UI elements. Buttons and scrollbars are great. We need something more primitive than the DOM and CSS. Houdini is a solid start here.
Well, it’s clearly what the Google docs team wants. And it would yield higher performance for other similarly complex web apps (eg Figma). And allow native UI development in more languages (Blazor). It also looks to be the sort of thing the Flutter team want for web builds. And it could work well for the base system of chromeOS too.
For whatever reason, Google invests hundreds of millions each year into chrome, and trusts their engineers’ leadership on how to make it succeed. The question in my mind is if browser engineers themselves decide to push in this direction.
Chrome has been pushing Houdini [1] for years. It doesn't have special WASM integration right now AFAICT but it is basically a lower level layout & rendering API for the browser.
I've looked at Houdini again and I'm not convinced.
First, because it's more like OpenGL 3 (add more powerful APIs) than Vulkan (clean room design).
Second, it seems mostly abandoned. The page you cited lists multiple sub-proposals that have "No signal" even from the Chrome team. All mentions of Houdini I can find on developers.google.com are from 2018. I can't find anything about Houdini integration with WebAssembly, which is what I'd expect if development was ongoing.
Overall, I'm seeing everything I would expect to see in the timeline where Mozilla has no intention of ever implementing Houdini, and Google has decided it's not worth pursuing beyond what's already implemented.
The killer feature of Google Docs is the real-time collaboration. People willingly gave up a lot of editing and layout functionality to get that. It was so much better than sending drafts of documents back and forth in email.
I feel the need to argue that the browser is not the browser engine. An app sitting in a chrome tab is significantly different than an app built on electron, they just share some rendering code paths.
Electron apps have shown that you can use a browser's rendering engine to make high quality apps distributed on multiple platforms. They also have the benefit of persistence, filesystem access, hooks into native code should you need them (not WASM - mind you), you can implement true multithreading and explicit SIMD optimizations. You don't have memory limitations, and you don't have to worry about browser sandboxing, malicious or well intentioned extensions that break the experience, etc.
The browser is not the same platform as electron. I would guess that Google Docs would function much better in electron than on the web.
> An app sitting in a chrome tab is significantly different than an app built on electron, they just share some rendering code paths.
That isn't really true, Electron is basically a thin veneer over the Chrome browser, with NodeJS tacked on the side. Just take a look at the source code.
> Electron apps have shown that you can use a browser's rendering engine to make high quality apps distributed on multiple platforms.
Electron has shown that you can use a re-skinned browser and NodeJS to ship applications on all platforms capable of running Chrome. That ranges somewhere between "acceptable tradeoff" and "absolute overkill", depending on the application.
> You don't have memory limitations, and you don't have to worry about browser sandboxing, malicious or well intentioned extensions that break the experience, etc.
You still do have almost all of the limitations of a web browser in your rendering code, and you have none of the features of the web browser outside of it. The bridge between the two is inefficient.
Yeah, I'm wondering why Google isn't building a desktop version of their office apps in electron. I can practically hear the collective sigh of relief upon those landing in users ' laps.
> It was indeed a very strong marketing move for... decades to convince people, like smart people, that document editing can be a web-based thing.
I think this is overly reductive. There was a technical problem driving some of this; namely - document collaboration sucked (to some degree still does).
Moving documents online was a tradeoff - making the editor web based solves a bunch of problems but causes some other ones; desktop based cloud backed editing didn't exist (not that it's perfect now) at a time when you could get useful collaboration done with web based editors.
I'm not saying this was the only thing going on, but reducing it to just "marketing" misses the mark, I think.
The way that word processors are designed, essentially as very smart linked-lists of objects, would've actually allowed for the document collaboration very early on. We can perhaps speculate dozens of reasons why dis did not happen, but I guess it was for strategic reasons. But it will and is happening.
Is about right making the point that IMHO the desktop office processor is far from dead, actually I would imagine a comeback of desktop UIs because they are so much easier to get right, especially when you have complex forms (which all business software has) or custom GUIs (such as those in software like Blender, Photoshop, Lightroom, etc).
Question is did people really needed the collaboration feature so much, or as much as it was praised for decades... When it shows that source code (which IS one very important content) is being developed not collaboratively in real-time in the browser, but with the aid of various version control systems (CVS, SVN, GIT etc.) that is neither real-time, nor collaborative in the sense that Google DOX is.
So the whole collaboration thing is fun to have, great thing to demo, but perhaps not the killer feature.
Question is whether other features were more important and thus got implemented in the office packages. Such as enterprise integration capabilities and very powerful and well crafted WYSIWYG that is only possible with custom built engine.
Let's be honest - the most complex apps that is typically running on an average desktop OS is the browser and the word/spreadsheet processor. Back in the day the browser was not a VM and was not that complex. And as OpenOffice showed - this is not very easy to get right. As WPS Office (the Chinese office) showed - even if the presentation layer is fast/correct, it is not really that easy to (originally) come up with it nor integrate it with other enterprise services.
One may wonder whether MS Office was created to run best on Windows, or was it that Windows is made so to enable good run of MS Office and the integration of all this mandatory software that constitutes the modern enterprises... (again, trying to be as unbiased as possible)
> Question is did people really needed the collaboration feature so much, or as much as it was praised for decades... When it shows that source code (which IS one very important content) is being developed not collaboratively in real-time in the browser, but with the aid of various version control systems (CVS, SVN, GIT etc.)
This is a good point. I don't think realtime collaboration is so important, but multiple author collaboration is. And "track changes" is a sort-of good-enough solution, but painful.
I've had good luck collaborating on documents (research papers) using latex and source control, but that assumes (a) participants are comfortable with both and (b) the storage format is amenable to revision control. Most word processing doesn't work well like this because you can get the document into a broken state in ways that are hard to recover from, and many of the users have no mental workflow map for "source control"
TeX/LateX or orgmode/Markdown type approaches have an advantage here for complicated collaboration.
These days a lot of collaborative stuff is being done outside of spreadsheets and word processing docs, the lines are blurrier and the collaboration is broader. In the "old days" a wiki might have done the trick for this but people want richer environments too. Not sure what he answer really is.
Microsoft Word and Pages both also have web apps, for years, that are 'bottlenecked by rendering performance' (would put it as 'clearly would be improved by better rendering performance', as you're noting)
Google docs is worth it for the coorporation, but if you are writting for yourself, or anything seriously it is simply not good enough, but I don't think the performance is the issue.
This mode of argument seems odd to me. Google is announcing a solution to the problems they were having with the platform. Wouldn't the criticism "Perhaps the browser is the wrong platform for document editing" only be appropriate if Google was complaining that they have been unable to fix the problems?
The fact that, while developing for a given platform, you can encounter problems and fix them, doesn't seem to imply that there's something wrong with your choice of platform.
The browser is the wrong platform for anything that isn't an HTML document, and not only for performance reasons, but perhaps much more importantly : for interface reasons.
For instance : in your typical windowed program, when you press "Alt", it's supposed to show the Menu, which you can then quickly navigate using keyboard shortcuts. You can't do that properly inside the browser because it's going to conflict with the browser's own Alt-Menu.
Based on inspecting the DOM of the read-only preview document they link to, my guess is that they will be using traditional DOM elements for much of the editing UI. There appear to be many empty DOM elements that are there to hold various toolbars and other UI elements. And for what it's worth, there seem to be empty DOM elements intended to be read by screen readers.
Every major ABI is listed here as containing the same mistakes. I'm inclined to think the people who designed these ABIs were smart enough to understand the consequences of their design decisions.
I don't know whether this author is correct or not, but my gut is there is something missing here with respect to non local control flow (like exception handling, setjmp/longjmp, and fibers).
I love seeing others bring up Chesterton's fence; it's been a reference that comes to mind with quite a lot of the WTFery I've encountered in my career (usually it remains WTFery even when looking for underlying reasons, but it at least helps remind me to question my instincts).
I don't really know enough to weigh in on this, but I can say that having pursued a lot of WTFish things in my career so far, 90% of the times I've encountered bad decisions, the explanation for it was either "it was done that way because legacy reasons" (i.e., it had to be done that way then, the reason it had to be has changed, and now it would break things to do it 'correctly') or "it was easier" (i.e., at the time the badness wasn't really going to affect anyone, or not measurably, or was very intentional tech debt, and it's only 'now' that anyone is noticing/caring).
I've seen people make bad architectural decisions that now the company is stuck with. And it comes down to just the fact that it was a bad decision, no second guessing needed.
I've also seen "bad" decisions made due to outside constraints. These decisions look like bad decisions, except that if you try to "fix" those decisions, it becomes a lot harder than it looks.
Don't get me wrong, there are plenty of times it was cluelessness. I'm just saying, I find myself going "this is stupid" far more often than it -was- stupid. It might be now, but the reasons for it then sometimes made sense.
In this case, "it was done that way because legacy reasons" is close, but the real answer is "it was done that way because we hadn’t yet invented the parts of compiler theory required to create compilers that enforce this constraint at the type level."
All this compiler sophistication represents a step backwards for binary interfaces. For example, C++ compilers emit such incredible machinery that it's essentially impossible for foreign code to interface with the compiled objects at the binary level. As a result everything eventually gets reduced to the C ABI: simple symbols and calling conventions.
That's... what we're talking about. Simple symbols with calling conventions.
The rules for this proposed ABI are exactly the same as the existing amd64-SystemV C ABI, with one difference: the stack-to-stack copies aren't generated at the call-site; instead, the generated code at the call-site passes the address (in a register, or spilled to stack) for what it would have copied. The compiler generates the stack-to-stack copy in the generated function's prologue, using the address it was passed. Nothing more, nothing less. It's just moving the required location for certain generated code across the linkage, and keeping a temporary alive a little bit longer to make that work. (And in exchange, the temporary that the local stack variable gets put in isn't created at the call-site, so the register-file "pressure" of the change is net neutral.)
This is no more or less complex than the current ABI. It doesn't create more exceptions or edge-cases than the current ABI. It doesn't make the ABI harder to implement. The only thing it does, is choose differently in the matter of a basically-arbitrary choice of where to put some generated glue code (the stack-to-stack copy).
The only practical upshot of this change, is that this enables compilers to sometimes do an optimization that they can't currently do, because doing said optimization would go against the rules of the amd64-SysV ABI (i.e. a caller that pushed a register instead of copying the value wouldn't be an amd64-SysV caller any more, and wouldn't be compatible with precompiled amd64-SysV callees any more; and vice-versa for the callee.)
But if-and-when a compiler does do that optimization, it's internal to the generated function. It doesn't mean that there are two potential callee "signatures" under the proposed ABI. There's only one.
Here's what the proposed ABI would probably say about stack copies:
> "The caller always passes large values by reference; the callee always receives them by reference. If the callee is taking a parameter pass-by-value, then it's up to the compiler of the callee to insert code into the callee's function prologue to turn the passed reference into a stack-local copy of the referenced data."
With that particular legalese, the callee's generated copy is still "required" by the spec, but its effects are now also "hidden" from the caller — i.e. its observable results are no longer leaking across the linkage. Therefore, the compiler is now empowered to optimize out the callee copy, as long as it can ensure the resulting code has observably equivalent results from the caller's perspective.
Note that this isn't anything the person implementing the ABI targeting code in the compiler has to worry about. They just write the code to generate a callee function prologue that does a stack-to-stack copy. It's the person writing the optimization pass that comes after that codegen step, who can now can take that stack-to-stack copy and — static proof of read-only access by the callee in hand — drop it out.
The optimization opportunity being enabled by the change, isn't part of the ABI's spec. The proposed ABI is just about moving the stack-to-stack copy into the callee. What the compiler chooses to do when targeting an ABI where the callee does stack-to-stack copies, is up to the compiler. Presumably, it will do "whatever fiendish things it can" at -O3, and "nothing much different" at -O0. Like usual.
And either way, the linkage itself looks the same. The optimization doesn't change the linkage. Any and all tooling that examines the linkage — debuggers, disassemblers, tracers, etc. — would see the same thing, whether the optimization has occurred or not. Because the optimization isn't part of the linkage; it's internal to the codegen of the callee, enabled by the (uniformly!) modified structure of the linkage.
Yup, there's also time dependence. Perhaps someone wrote some software in COBOL that is hard to maintain now. But rewritng it may not be worth the opportunity cost now, especially for well-tested systems that have been around for a long time and which have critical failure modes. Sometimes it's better to leave things alone and work around them, even if it results in an uglier design.
It didn't matter before, as compilers were not optimizing as much, code had a much closer 1:1 correspondence to assembly (if you are passing it by pointer and not register, you would want to make that clear in code).
It's much easier to implement in simple compilers. On the side of the callee you don't have to check if you manipulate your arguments, which is generally hard. Being able to manipulate your arguments is another shortcut for keeping the compiler simple.
On the side of the caller you don't have to check if you hand out a mutable pointer.
Also finally and most importantly: memory access was much cheaper in terms of cpu cycles. Just look at cdecl: all parameters are passed on the stack instead of registers.
Our current calling conventions stem from performance hacks like fastcall that were only optimizing for existing code (you pass big structs by pointer by convention).
> my gut is there is something missing here with respect to non local control flow (like exception handling, setjmp/longjmp, and fibers)
(Post author.)
Mechanically, what happens is essentially the same as what ms/arm/riscv do: the caller creates a reference and passes it to the callee. The only difference is that the callee is more restricted than it would otherwise have been in what it can do with the memory pointed to by that reference. So I don't think that there can possibly be any implications for non-local control flow.
Doesn't the referenced data have to be guaranteed to outlive the callee, which would only be true if the callee is guaranteed to return to the calling scope?
You can get around the immutability of the reference if your compiler implements the ABI with copy on write semantics, which I think is a reasonable compromise. But I'm still not certain how you would handle arbitrary control flow that the compiler may not be able to reason about.
If for example your arguments may be behind const references, how would you implement getcontext/swapcontext for your ABI? If everything is an integral value in registers or on the stack then it's really easy, but i would think it would have to be a compiler intrinsic if it depends on the function signature of the calling context, in order to perform the required copies.
Well for one, the language says a copy is made at the time of the function call, and it's perfectly valid to modify the original before the copy is finished being used. So pretty much any potentially aliasing write or function call in the callee would force a copy, and as he notes C's aliasing rules are lax enough that that's most of them.
Then if you care about the possibility of signal handlers modifying the original... you pretty much have to make a copy every time anyway.
Plus any potential concurrency synchro point existing would force a copy, plus using any unknown function, etc.
Using rust and propagating the single writer xor multiple readers requirement in an ABI, this might be interesting. But with C/C++, I'm afraid copies would be forced "all" the time.
There's still a lot of functions which don't call unknown functions before accessing an argument passed by value, don't take the argument's address, etc. There are many simple functions such as this one:
That one would gain a speed-up and code-bloat reduction from the proposed ABI, and there are many like it.
But even if every single function had to fall back to making a copy, the argument is that there's still a significant code bloat saving by putting the copy in the callee rather than in the caller. After all, the instructions necessary to make a copy takes some space, and with the proposed ABI, those instructions are put in the called function, rather than in every function call. Most functions are called more than once, and all functions are called at least once (hopefully), so anything which can be changed from O(number of function calls) to O(number of functions) is an improvement.
Exactly, see my example elsethread. Also in C and derivatives distinct objects are guaranteed to have distinct addresses. Implicit sharing would break this.
It wouldn't. The compiler would just have to generate the copy when the standard demands it (such as if the function body takes the address of the object).
Yes but then in many cases either (or both!) the caller and the callee might need to make a copy defeating the point of the optimization or even being worse than the original.
In many cases the callee would have to make a copy, yes. However:
1. In many cases, no copy would have to be made. There are lots of small non-complex functions out there where the compiler can prove that it's safe to not make a copy.
2. In many other cases, a copy has to be made. But the copy is made by the callee, not by the caller. That means that all the instructions necessary to copy the argument ends up in the binary once in the callee, rather than once for every function call, leading to less code bloat (which has its own performance advantages).
In fact, a stupid compiler could just always make a copy without analyzing the function body. This would result in a compiler which generates code that's about as fast as it would be with current ABIs, but with a smaller size.
You have to make a copy on the caller or the callee if the address of the object escapes, so you might end up with two extra copies even if nothing in the program mutates the object.
I don't understand how you achieve extra copies? My understanding is that the caller would never make a copy, it would always pass a pointer to large structs. So the absolute worst case, unless I'm missing something, is that we end up with the same number of copies as we do today (i.e one copy per large struct passed as a parameter).
struct A { int m; } global = {5};
int f(struct A a) {
global.m = 7;
return a.m;
}
int main() {
f(global);
// need to make a copy of 'global' here
// otherwise f will return 5 instead of 7
}
Hey, I've realized that there are two understandings of the proposed ABI: One in which the only promise is that the callee won't modify the object through the pointer, and one in which the callee promises to not modify the object through the pointer and the caller promises that nothing else will modify the object. Maybe you could shed some light on it since you're the author?
In the first version, the worst case situation is that only one copy is made, and it's always made by the caller. However, the caller has to make a copy if the object is referenced after any function is called, because that function might otherwise modify the parameter if a pointer to the caller's version of the object has leaked out somewhere.
In the second version, the worst case situation is that two copies are made where old ABIs would make just one copy (if the caller has to make a copy and the callee has to make a copy). However, the callee would only have to make a copy if it actually does something which might modify the object through the pointer passed as an argument, so the optimization would apply for more functions.
I think it's fairly clear from the article that your intended ABI is the first version, due to the sentence "In the event that a copy is needed, it will happen only once, in the callee, rather than needing to be repeated by every caller" . But in this comment, you're implying that the caller makes a copy if it can't guarantee that nothing else has a pointer to the object?
I should have been clearer; my intention was your second interpretation. The copying happening only once is predicated on the assumption that the struct wasn't aliased; since it's unlikely to be aliased if you're passing it around by value.
Your first interpretation is essentially what the ms/arm/riscv abis do. The reason I don't think that works as well is—
In general, it's rare for functions to mutate their parameters by value. We can effectively treat this as an edge case, and 'compensate' by making copies in the callee when necessary. But, when does the caller need to make a copy?
Version 1: whenever the object is aliased before the call, or read from after it
Version 2: whenever the object is aliased before the call
I think using the same struct multiple times is something that happens relatively frequently, so compared with v1, v2 elides a lot of caller-side copies. In exchange, it adds a relatively small number of callee-side copies. Which, despite the few pathological cases, seems likely to be overwhelmingly worth it most of the time.
Sorry, I messed up. I meant to write that in the first version, the copy is made by the callee. If the copy is made by the callee, then the callee can avoid a copy if it can guarantee that the caller's version of the object isn't changed before the callee uses it, and at most one copy is made.
Anyways, your intention is clear now at least. I'd be a bit worried about an ABI which might produce two copies for one parameter. It would be interesting to analyze a bunch of real-world code and see A) how often would my version create a copy, B) how often does the MS/ARM/RISC-5 version have to make a copy, C) how often would your version make a copy, and D) how often would your version require two copies.
Would also be interesting to see an analysis of code bloat due to copying parameters.
> If the copy is made by the callee, then the callee can avoid a copy if it can guarantee that the caller's version of the object isn't changed before the callee uses it, and at most one copy is made.
So the callee has to know what every caller of it will ever do? That's ... an ABI. The whole point is that functions can exist in a vacuum without knowledge of who they will be called by.
To be clear, I think it would be really cool if compilers could generate ad-hoc calling conventions using lto to optimize spillage, but that's not really useful as an ABI.
> would be interesting to analyze a bunch of real-world code and see A) how often would my version create a copy, B) how often does the MS/ARM/RISC-5 version have to make a copy, C) how often would your version make a copy, and D) how often would your version require two copies.
> Would also be interesting to see an analysis of code bloat due to copying parameters
The ABI I had in mind was similar to the AArch64 ABI:
>If the argument type is a Composite Type that is larger than 16 bytes, then the argument is copied to memory allocated by the caller and the argument is replaced by a pointer to the copy.
But with a slight modification to put the copy in the callee:
>If the argument type is a Composite Type that is larger than 16 bytes, then argument is replaced by a pointer to the copy. The callee copies the pointed-to object into memory allocated by the callee.
This immediately has the advantage of less binary bloats, because the amount of parameter copying instructions in the binary will become O(number of functions) rather than O(number of function calls). (As an aside: That can probably be a huge advantage for C++ with its large, inlined copy constructors.)
When the copy is made in the callee, we can start identifying cases where a copy isn't necessary, or cases where only certain parts of the struct has to be copied. It would have to be fairly conservative though, since unlike with your ABI, there would be no guarantee made by the caller that there are no other references to the parameter.
I think my version is a clear and obvious improvement over the status quo, with decreased binary sizes and as good or better performance. Your version is more risky where the worst case is two copies per large parameter but, your version will probably achieve zero copies in way more cases than my version. "Low risk / medium reward" versus "medium risk / probably high reward".
---
Anyways, I might end up writing a blog post on this stuff. If I do, it will refer to your blog post. How should I refer to you? Moonchild or elronnd or something else?
If the address of the object escapes on the caller side then it has to make a copy as the object could be mutated or even just break the distinct address guarantee of the language.
I still don't understand, sorry. If the callee does something which could cause the caller's object to change, such as calling an unknown function or modifying through another pointer which might alias the parameter, the callee would just have to make a copy.
Could you provide an example of a situation where there would be more copies made using the proposed ABI than in traditional ABIs?
Sure, if calling any external function or writing though any pointer would force the callee to copy the object then yes you can have only the callee do the copy, but then it seems that this optimization would apply only to a very small subset of functions.
Right. That was my understanding, but I now see that there are more ways to understand it. I don't know which is correct, so I wrote a response to moonchild's comment here: https://news.ycombinator.com/item?id=27091726
> A correctly-specified ABI should pass large structures by immutable reference
is just not possible. CPUs don't know about `const`. So you have to work with the assumption that functions that you call can do anything to their arguments. Thus copies cannot be avoided.
An ABI also has a concept of defined and undefined behaviour. You can design an ABI that is fully protected against abuse but often the performance penalty for that will be huge.
Instead what you'll do is specify the constrained inputs and expected output behaviour. From there you can out anything that violates those constraints as non-conformant. As long as you maintain those constraints between versions, there's no ABI breakage.
Also you can absolutely have constant references in an ABI. There may be ways of ignoring the const depending on how you design the ABI but they will be obvious abuse.
CPUs actually do know about const; it's called a read-only page.
Besides, that's irrelevant. There's nothing stopping my function from following every pointer on the stack and smashing up its contents; are you going to defend against that, too? If not, how is this any different?
I haven’t seen a one’s complement machine in decades but at the time C was standardized here were still quite a few (afaik none had a single-chip CPU, to get to your question). But since they existed, the language definition didn’t require it and some optimizations were technically UB.
The C++ committee decided that everyone had figured this out by now and so made this breaking change.
Having a mostly statically linked executable handle this rather than some bastard child of virtual environments and docker images is a dream come true.
Shoutout to the Tools teams which develops cross, it's really amazing, did a project ago and had some problems to compiling static with rustls (OpenSSL really bugs with me, who knows why) do I tried Cross and felt in love, just works
If you have problems using musl with some libs, give it a go, you gonna love it ;P
Time Machine can't run on my Mac because there's not enough space on disk for it to run. Third party backup services that can function with the comically small default SSDs are preferable.
You have to backup more regularly than every two months...
And Apple replaces the entire motherboard if a component on it fails. The agreement that you may lose data has been around awhile and it's just boilerplate. When mucking around on a board they aren't going to guarantee anything - and I don't know if third party repair shops would do that either. There is always the chance someone screws up and breaks something.