charles-salvia

Joined 10 years ago

Karma
618
Submissions
136
Member since
Dec 29
I develop software that works sometimes.
View on Hacker News

Recent submissions

Comment · 9 years ago
If we were to somehow perform a Principal Component Analysis on the amorphous, contradictory mess of "hippie ideals", we could probably distill them down to something like a call to implement a post-scarcity, socialistic society with few restrictions on human social behavior.

Of course, that kind of radical change isn't achieved by smoking pot and playing the guitar in downtown San Francisco. It's achieved by major technological changes that would make such a society even functionally possible, like practically-unlimited renewable energy sources. Needless to say, nobody involved in the 1960s counter-culture movements was in any position to actually implement the kind of changes needed to realize the grand vision of an ideal hippie society. (Some of them tried to do the next best thing, and form their own mini-societies in communes out in the country, all of which ultimately turned out to suck.)

I would also note that another 1960s icon, Gene Rodenberry, at least seemed to realize that the kind of changes needed to implement a hippie utopia would likely only be possible after many other practical societal problems were solved via technology.

Comment · 9 years ago
>> What concentration camps reveal is that modern people are squeamish about killing.

Well, there's a difference between exterminating a foreign and/or conquered city-state, and isolating/quarantining undesirable sub-groups from within a larger civilization (often for reasons that are more ideological than political). What the Mongols, Romans, Assyrians, etc., did was less like isolating an ethnic sub-group and more like inflicting punishment upon a city-state for not paying tribute. (Also, I think the Assyrians would also export the population of a city-state and resettle them elsewhere, to remove their national identity, just as often as they would kill and/or skin-alive everyone in a targeted city-state.)

It's probably worth noting that what happened recently to the Yazidis in North Iraq was closer to what used to happen in antiquity.

Comment · 9 years ago
I'm a bit confused here.

>> Most operators in C++, including its memory allocation and deletion operators, can be overloaded. Indeed this one was.

Okay, well, firstly - the issue here seems to be a problem with the implementation of std::allocator, rather than anything to do with overloading global operator new or delete. Specifically, it sounds like the blog author is talking about one of the GNU libstdc++ extension allocators, like "mt_allocator", which uses thread-local power-of-2 memory pools.[1] These extension allocators are basically drop-in extension implementations of plain std::allocator, and should only really effect the allocation behavior for the STL containers that take Allocator template parameters.

Essentially, libstdc++ tries to provide some flexibility in terms of setting up an allocation strategy for use with STL containers.[2] Basically, in the actual implementation, std::allocator inherits from allocator_base, (a non-standard GNU base class), which can be configured during compilation of libstdc++ to alias one of the extension allocators (like the "mt_allocator" pool allocator, which does not explicitly release memory to the OS, but rather keeps it in a user-space pool until program exit).

However, according to the GNU docs, the default implementation of std::allocator used by libstdc++ is new_allocator [3] - a simple class that the GNU libstdc++ implementation uses to wrap raw calls to global operator new and delete (presumably with no memory pooling.) This allocator is of course often slower than a memory pool, but obviously more predictable in terms of releasing memory back to the OS.

Note also that "mt_allocator" will check if the environment variable GLIBCXX_FORCE_NEW (not GLIBCPP_FORCE_NEW as the author mentions) is set, and if it is, bypass the memory pool and directly use raw ::operator new.

So, it looks like the blog author somehow was getting mt_allocator (or some other multi-threaded pool allocator) as the implementation used by std::allocator, rather than plain old new_allocator. This could have happened if libstdc++ was compiled with the --enable-libstdcxx-allocator=mt flag.

However, apart from explicitly using the mt_allocator as the Allocator parameter with an STL container, or compiling libstdc++ to use it by default, I'm not sure how the blog author is getting a multi-threaded pool allocator implementation of std::allocator by default.

[1] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

[2] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

[3] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

Comment · 9 years ago
The C++ delete[] operator doesn't take a size parameter either. This is neither here nor there, and unrelated to the problem the blog post is talking about.
Comment · 9 years ago
Comment · 9 years ago
>> Our brains are fallible, and so only approximately equivalent to Turing machines; and even ignoring that can only compute every computable thing given both infinite error-free storage capacity (which they don't have internally or externally) and sufficient time to execute the necessary steps of the computation.

So are actual computers. They're just "less fallible" and closer to a Universal Turing Machine than human brains in certain ways. A Commodore 64 is also incapable, in practice, of computing certain computable functions, due to memory limitations and what have you, but nobody would really claim a Commodore 64 is not Turing complete.

Comment · 9 years ago
The practical difference is that with async I/O, there's less overhead because you don't need a separate thread for each blocking I/O operation. It's the difference between using a single-threaded event loop to demultiplex between 10,000 sockets, and using 10,000 threads to read one socket each. The former strategy has way less overhead.

Of course, many high-performance, I/O intensive applications like web-servers can effectively make use of a combination of multiple threads and I/O demultiplexing as well.

Comment · 9 years ago
k, along with j, is also often an index.

Of course, this mathematical convention carried over into programming as well, with i,j, and k serving as index variables.

Comment · 9 years ago
> It's odd how this is portrayed as a negative aspect of Japan's militarism, when the Allies were fighting the same war with the same attitude.

That's not the point, obviously. The point is Japan's militarism combined with their utter over-the-top brutality and expansionist agenda.

Comment · 9 years ago
The "lone genius" is somewhat of a myth, but also has a certain amount of truth to it. For example, Einstein was certainly a lot smarter than the average person - indeed, probably a lot smarter than most highly-accomplished scientists and engineers. However, he also was at the right place at the right time, and would never have come up with General Relativity had it not been for the work of his predecessors, such as, e.g., Riemann, who enabled Einstein to think of space-time in non-Euclidean terms, etc.

I think the biggest problem with the "lone genius" mentality is that it encourages the popular notion that "if it wasn't for Einstein, we'd never have General Relativity." But of course, this is most certainly false. If Einstein never existed, someone else would have eventually noticed problems with Newtonian mechanics over large distances, and ultimately applied Reimannian geometry to spacetime as a solution. It may have happened years or decades later, but overall scientific progress is very rarely strictly dependent on one individual.

Comment · 9 years ago
Ethics aside, at a certain point, you realize you can make a lot more money legally and legitimately using your technical skills than through any sort of "clever" technical scheme that involves hacking odometers or scamming people in some way.
Comment · 9 years ago
Okay, well - never knew this. But that example seems really cherry-picked. Many NY street names are just numbers, even in other boroughs outside Manhattan. Many streets in the Bronx are just a number (130-something street to 230-something street, carrying over from upper Manhattan).
Comment · 9 years ago
I've lived in NY my whole life, but am not familiar with this stereotype about unpronounceable names. Apart from Kosciuszko there aren't too many difficult to pronounce names of bridges/tunnels/express-ways, etc. Kosciuszko is a Polish name - the bridge is named after a Revolutionary War general, not a local New York politician. Most other bridges/tunnels/express-ways are named after famous American politicians (Washington/Lincoln/RFK), or are just named obvious descriptive things like "Brooklyn-Queens Expressway". Every now and then some bridge gets renamed (Triboro -> RFK), but nobody cares. AFAIK the only bridge named after a local New York politician is the "Ed Koch" bridge, but nobody calls it that anyway.
Comment · 9 years ago
Basically, the main problem with signalfd is a problem with the Linux implementation of signals in general: if your program requires some kind of logic where each individual signal delivery somehow "counts" in some way, you may run into a problem because the kernel may coalesce/collapse multiple identical signals delivered consecutively into a single signal delivery. So if your program has some kind of logic that relies on responding to each individual signal, you may have a problem. (Note that this problem does not apply to POSIX real time signals.)

But as far as I know, the only reason you'd ever care to actually count individual signal delivery events is with SIGCHLD. So when waiting for SIGCHLD, using signalfd is not sufficient. You'd need to also use one of the wait/waitid/waitpid variants to ensure that you can respond appropriately to each individual SIGCHLD delivered.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton