Hacker Newsnew | past | comments | ask | show | jobs | submit | rwallace's commentslogin

Happy new year from Ireland!

Sure. If you feel the need to write "this is shitty code", fair enough, I'm fine with making allowances for that kind of language. But please leave it at that, instead of also insulting the people who wrote it. There are, unfortunately, plenty of ways for bad incentives to result in competent people creating bad products.


In general, if a program is not a Web browser, I do not want that program getting clever with displaying a URL as an active link. Just show it as the URL, https prefix and all, so I can see where it will be taking me if I copy it into the browser. (This is one of my very few gripes with Google docs.)


I disagree with your second sentence above. I think it is shallow dismissals that are inappropriate here. Conversely, I have upvoted a number of long explanations of interesting topics.

If you don't have time to write a detailed refutation, that's entirely understandable! But if you do, I would love to read it.

I did appreciate your paragraph length comment on the matter elsewhere in this thread.


My original comment was one of those "if you know, you know" things.

Topics age out very quickly on this site.

I have two lengths: aphorism or six pages. The graf that you so kindly praise raises more questions than it answers and I am not comfortable with that.

I am also not comfortable with spoon-feeding my own views, which are evidently idiosyncratic. At medium length, that is the effect. To marshal citations and evidence in order to re-attain objectivity really does explode the level of effort. It is worthwhile, but this is a quick-hit forum, things roll off the front page usually in about an hour or two.

The flip side of that is that there will be other opportunities.


Fair enough! If you ever have the time and inclination to write it up as a blog post or such, I would love to read it.


The topic of business-process analysis crops up often enough. I'll throw a few bricks the next time it does.

The topics of the roles of accountants and auditors crop up much less often, which is puzzling all by itself. But you absolutely cannot talk about ERP adoption without getting into those things up to the elbows.


To clarify a couple of things:

I'm aware of the reasons Linux uses doubly linked lists. I'm still of the opinion this design decision made a lot of sense in the 1990s, and would make less sense in a new project today. You may disagree, and that's fine! Engineering is constrained by hard truths, but within those constraints, is full of judgment calls.

I'm not a member of the evangelical Rust community. I'm not proclaiming 'thou shalt rewrite it all in Rust'. Maybe you have good reasons to use something else. That's fine.

But if you are considering Rust, and are concerned about its ability to handle cyclic data structures, there are ways to do it, that don't involve throwing out all the benefits the language offers.


Linux's use of pointer-heavy datastructures is largely justified even today. The low-level kernel bookkeeping requirements rule out many typical suggestions. Modern hardware suggests certain patterns in broad strokes, which are sound for mostly any software. But the kernel has the unique role of multiplexing the hardware, instead of just running on the hardware. It is less concerned with, e.g., how to crunch numbers quickly than it is with how to facilitate other software crunching numbers quickly. As someone else noted elsewhere in the top-level thread, unsafe Rust is the appropriate compromise for things that must be done but aren't suitable for safe Rust. Unsafe Rust is one of the best realizations of engineering tradeoffs that I've seen, and neither C nor safe Rust justify its absence. Rust is only a "systems" language with unsafe, and that doesn't drag Rust down but rather strengthens it. "Here is the ugliness of the world, and I will not shy from it."


Beautifully put, poetic even. The only problem is that, in (*actual).reality, unsafe Rust is difficult to read, difficult to write, difficult to maintain, difficult to learn, has zero features for ergonomics, and has poorly defined rules.

C and Zig have a big advantage for writing maintainable, easy to read unsafe code over unsafe Rust.


> The only problem is that, in (*actual).reality, unsafe Rust is difficult to read, difficult to write, difficult to maintain, difficult to learn, has zero features for ergonomics

All true.

> and has poorly defined rules.

The rules aren't so poorly documented. The options for working with/around them, like say using UnsafeCell, do seem to be scattered across the internet.

But you omitted a key point: unlike C and Zig, unsafe code in Rust is contained. In the Rust std library for example, there are 35k functions, 7.5k are unsafe. In C or Zig, all 35k would be unsafe. If you are claiming those 35k unsafe lines in C or Zig would be easier to maintain safely than those 7.5k lines of unsafe Rust, I'd disagree.


I agree that unsafe Rust is not comfortable or simple, but I think it is usable when appropriately applied. It should very scarcely be used as a performance optimization. The Rust devs are quite invested in minimizing unsoundness in practice, particularly with Miri. In coming years, I expect unsafe to be further improved. Over the entire ecosystem, Rust with judicious use of unsafe is, in my opinion, vastly superior to C, unless the C is developed stringently, which is rare.


So, as an example, you'd be happily spending an extra allocation and extra pointers of space for each item in a list, even when that item type itself is only a couple of bytes, and you potentially need many millions of that type? Just so your design is not "from the nineties"?

An extrusive list needs at least 1 more pointer (to the item, separate from the link node), and possibly an additional backpointer to the link node when you want to unlink that node. It also adds allocation overhead and cache misses.

Intrusive lists are one of the few essential tools to achieve performance and low latency.

Or were you thinking of dynamically reallocating vectors? They are not an alternative, they are almost completely unusable in hardcore systems programming. Reallocating destroys pointer stability and adds latency, both very bad for concurrency.


I’m sorry, I did not intend to accuse you of being part of the evangelical community. Your article only prompted the thought I shared.

On the technical point, I think I do disagree, but open to changing my mind. What would be better? I’m working on an async runtime currently, written in C, and I’m using several intrusive doubly linked lists because of their properties I mentioned.


No problem!

As to what would be better - this is also a reply to your sibling comments above - I don't have a single across-the-board solution; the equivalent of std::vector everywhere is fine for some kinds of application code, but not necessarily for system code. Instead, I would start by asking questions.

What kinds of entities are you dealing with, what kinds of collections, and, critically, how many entities along each dimension, to an order of magnitude, p50 and p99? What are your typical access patterns? What are your use cases, so that you can figure out what figures of merit to optimize for? How unpredictable will be the adding of more use cases in the future?

In most kinds of application code, it's okay to just go for big-O, but for performance critical system code, you also need to care about constant factors. As an intuition primer, how many bytes can you memcpy in the time it takes for one cache miss? If your intuition for performance was trained in the eighties and nineties, as mine initially was, the answer may be larger than you expect.


Even if you just go for big-O, don't forget that a resizable array won't give you even amortized O(1) delete in many cases. This alone is likely prohibitive unless you can bound the elements in the container to a small number.

And if you're trying to trade away good big-O for better cache locality, don't forget that in many cases, you're dealing with stateful objects that need to be put into the list. That means you likely need to have a list or queue of pointers to these objects. And no matter how flat or cache-friendly the queue is, adding this indirection is similarly cache-unfriendly whenever you have to actually access the state inside the container.


Or unless delete is a rare operation. So yeah, to make the best decisions here, you need to know expected numbers as well as expected access patterns.

As far as I can see, you are indeed going to incur one extra memory access apart from the object itself, for any design other than just 'Temporarily flag the object deleted, sweep deleted objects in bulk later' (which would only be good if deleted objects are uncommon). It still matters how many extra memory accesses; deleting an object from a doubly linked list accesses two other objects.

It also matters somewhat how many cache lines each object takes up. I say 'somewhat' because even if an object is bulky, you might be able to arrange it so that the most commonly accessed fields fit in one or two cache lines at the beginning.


Yes, that was exactly the reason. CJK unification happened during the few years when we were all trying to convince ourselves that 16 bits would be enough. By the time we acknowledged otherwise, it was too late.


In several similar incidents, it was clear that the, or at least a major, cause of the accidents, was that the officers on watch had been forced to work overtime and deprived of sleep to the point of cognitive impairment.

How many hours had the officer on watch in this case worked that week? How many hours of sleep did he have?

And why is no one except me asking those questions?


> Lessons

> It would be wrong to entirely blame the inexperienced OOW and poor performance of the bridge team for the incident, the investigation showed there were management failures that extended to the highest levels of the Navy. The pressure caused by the operational tempo, something the RN and USN would recognise, resulted in inadequate training time and personnel lacking sufficient experience in relation to their responsibilities.

Sounds like other people have asked. And the lack of time for sleep is only one aspect of the answer.


I read that paragraph, but my reading of it was different from yours. As far as I can see, it only discusses training time and experience. No mention of time for sleep.

Though yes, I do give it credit for going at least a little of the way - not far enough, but a little - in pushing back on the 'human error' scapegoating, in favor of asking questions about procedures and policies.


Point. I read the sleep deprivation meaning into the phrase "pressure caused by the operational tempo, something the RN and USN would recognise" - because I'm somewhat familiar with the subject.

Try a search on "naval officer sleep deprivation", and notice just how many military, government, and adjacent sites have been talking about that specific problem. (For me, its role in accidents and collisions pops up in the 2nd sentence of Google's AI overview.)


Most likely answer, based on [1] is that this was investigated and not a contributing factor. I infer this from thinking that investigators know for sure that the operational awareness of the watch can be impacted by watch schedules.

Training for the test versus training for operational deployment.

[1] Safety Investigations by Other Countries - https://msiu.gov.mt/wp-content/uploads/2022/12/PDF-Safety_In...


This is Norway. Nobody is forced to work to the point of sleep deprivation, doubly so in the public sector.


I predict that it will never make sense for artificial neural networks to directly generate machine code, for most of the same reasons it doesn't make sense for biological neural networks to do so.


I'm not aware of any CPU invented since the late eighties that doesn't have paged virtual memory. Am I misunderstanding what you mean? Can you expand on where you are getting the 4x number from?


I doubt any CPU has more levels of address translation, caching, and other layers of memory access indirection than AMD/Intel 64 at this point.


That's an interesting question about the number of levels of address translation. Does anyone have numbers for that, and how much latency and energy an extra layer costs?


As I understand it, the philosophy dates from centuries before that, and was inspired at least in large part by the frequency of earthquakes there.


The philosophy of mujo (無常) goes back centuries, long before modern history — it’s about the natural impermanence in all things.

OS Yamato isn’t about erasing memory, but encouraging us to reflect on what we choose to keep. Sometimes, letting go is part of how we grow.

Appreciate the thoughtful pushback.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: