HNHacker News
TopNewBestAskShowJobs

uxcn

235 karma · joined January 6, 2015

https://twitter.com/uxcn_
submissionscomments
uxcn··on Is this prime?
x87 is largely deprecated. Try inspecting the code emitted for floating point by all the major compilers.
uxcn··on Is this prime?
My mental model of a CPU unfortunately tends toward x86.

> But of course, it might be possible to get that sqrt for free, too. Even if it takes 50 cycles, you might start one, do a few iterations without checking for ‘reached sqrt(n) yet’, and then start a loop testing for the limit.

On the CPU side, the branch predictor might make the sqrt free by pipelining it, but that starts to make the analysis a bit harder. Strange things can happen when you introduce branch prediction. The performance would also depend on ALU/FPU contention, hyperthreads, etc...

> If you really want to know for x_64, http://www.agner.org/optimize/ probably has the answers, but then, you would have to know the x86 instruction set, which is horrendous (compared to that 6502 or 68000). Even realising that there will be single, double and vector variants, the number of different instructions with ‘SQRT’ in their name I find in http://www.agner.org/optimize/instruction_tables.pdf is insane.

I've only just started reading Agner Fog's documentation (which is awesome), but it definitely seems like the place the find low level information of the ilk when it's needed. If you read through the instruction table though, you probably noticed there are fsqrt and (v)sqrt(p)(s/d). For most purposes, x87 is actually deprecated and SSE2, the latter, is preferred for scalar floating point. I would guess the Mill devs might have some insightful comments.

> And of course, probably, something completely out of left field could well be the fastest way to do this (by a few ns, probably). For example, modern CPUs can count leading zeros in an integer. If that instruction is fast (for x86, that is not a given; ‘bit scan reverse’ was slow on some CPUs) subtract from 64/32/16, and halve, and you have a decent approximation to 2log(sqrt(n)) (using ‘if n has b bits, sqrt(n) has about b/2’)

I'm not sure that's quite right. Counting leading zeros is normally very fast if you have the instruction, but those two functions diverge pretty quick. For a constant cost, my guess is that the accuracy lost wouldn't be performance gained. The other point is that accuracy is fairly important if you're testing for primality.

uxcn··on Is this prime?
I honestly haven't looked into it in that much detail, but if I had to guess... probably. I'm not sure what the implementation used in hardware currently is, but at very least it's constant bounded,

Conversions are still somewhat expensive, but I do know compared to polynomial time or a large enough constant, it can be a better choice for an optimization. For example, computing log10 of an integer.

uxcn··on Is this prime?
The latency for sqrtss on broadwell is 11 cycles with a throughput of 4, where mul is a latency of 3 and throughput of 1. So, using some concrete numbers, sqrt is more expensive, but not polynomially or even an order of magnitude.
uxcn··on Is this prime?
You would normally use something like newton-raphson to compute a square root, which still isn't O(1) but converges fairly quickly. I would be very skeptical that n muls/adds would be faster than an sqrt, at very least for x86-64 since it is implemented as an instruction.
uxcn··on String Interning Done Right
> it would take quite a compiler to prevent the creation of an intermediate string. You could have every function return an iterator over the characters that would end up in the string, iterate over that to check whether the string already is interned, and if not, iterate again to allocate a new string, but I think it would typically be cheaper to create it and let he young generation garbage collector collect it.

I can't think of a language where you would always want to canonicalize strings at a global scope. For example, consider the case where you have a large number of threads and cores. Unless the strings are explicitly allocated on their own cache lines, any thread that references a string now has to worry about false sharing. You would also need to worry about the contention on the canonical store.

At a user level, in languages like Java, there's generally no reason to create any intermediate string if you're already reading from a direct byte buffer. This covers a fairly large set of use cases. There may be other techniques considering Java supports scalar interpolation now, but direct byte buffers have been the most effective in my experience.

uxcn··on String Interning Done Right
> Interning is a trade-off: you get decreased memory usage (if you use a lot of long-lived duplicated strings) and faster string comparisons (for pairs of strings that you do intern), at the cost of extra work to create the interned strings.

For garbage collected languages the benefit isn't only memory consumption, it's performance, since using canonical objects eliminates the additional allocations and garbage collections.

The string comparison argument is a bit of a dubious one though. Comparing length is only an integer comparison, and depending on the architecture, you can compare up to eight (or more) characters per cycle.

uxcn··on “I've been working at Mozilla for many years, from peak to decline”
It's not easy to get people to use something new. It's even harder to get a majority of people to use something new. If you consider that Microsoft has nearly the same magnitude resources, and their own widely deployed platform their browser is pre-installed on, it doesn't seem like a trivial accomplishment.

Firefox also had a bigger market share than Microsoft.

uxcn··on “I've been working at Mozilla for many years, from peak to decline”
Firefox has lost a lot of market share to Chrome (something like 30% vs. 14%). Internet Explorer has too. Considering Google only launched a browser in '08, it's pretty impressive they're at something like 50%.

Mozilla is still doing a lot of awesome stuff (web assembly, rust, servo, etc...), and I personally still choose Firefox over Chromium. As a user, I do have complaints about the direction on a number of things though.

One of the simpler things I'm surprised I haven't seen yet is a decent native text editor, considering how much relies on editing text in a browser.

uxcn··on C++17 and its Technical Specifications
Instead of exceptions, I personally prefer using assertions to verify things like preconditions; in which case if an assertion fails the software should generally crash before getting into a worse state. Arguably, if the software shouldn't crash it's probably not an exception. Assertions can also give an analyzer a set of preconditions to check. For example, Clang's static analyzer parses assert statements [1]. I'm not sure it uses them to verify the preconditions, but regardless it's still a good way to express them.

Another way to express constraints are attributes, which static analyzers (and optimizers) also use. For example, GCC has a number of function attributes [2] to express invariants about code.

[1] http://clang-analyzer.llvm.org/scan-build.html#recommended_d...

[2] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute...

uxcn··on Samsung ships the world's highest capacity SSD, with 15TB of storage
> Even if the DB server selectively read columns of each row (none of the common open source SQL databases do), they do so via the OS, which works in terms of pages. Reading a single byte of a page will cause a minimum of 4kb of IO to be made to the disk.

This is why I said it was high level, but hopefully illustrated the point. In addition to the disk page size, you also have all the various metadata associated with the file(s). So, reading a byte from a page can imply reading even more data than the block size (4KiB current).

> Now, unless you're using a DB server that uses O_DIRECT or POSIX_FADV_RANDOM (I just checked and Postgres doesn't), Linux will aggressively readahead at least (it's tunable) 128kb for any random read by default, so even issuing a one byte read to the kernel, device IO will still only occur in a minimum of 128kb chunks, with the remainder living in the page cache until userspace requests it.

AFAIK, Linux only reads ahead if it detects a sequential pattern, or if you specify POSIX_FADV_SEQUENTIAL (double normal). But, as far as the query is concerned, all of the data read that isn't necessary is effectively subtracted from the overall throughput.

I was trying to illustrate the importance of seek latency (~80us vs. ~9-14ms), but yes there are a myriad of other concerns when you're trying to maximize disk throughput.

uxcn··on Samsung ships the world's highest capacity SSD, with 15TB of storage
It's a throughput problem, not an activity problem. Normally, since the rows are a fixed size the dbms will lay them out sequentially on disk. So, when the database reads from disk unless you read every column in the row, the dbms has to skip over data. This is kind of a high level picture, but hopefully it illustrates the point.

Nearly all of the tick (>4GB/day) databases I've used aren't laid row oriented.

uxcn··on Samsung ships the world's highest capacity SSD, with 15TB of storage
> If you have a single table that's 100GB in size, you can parse through every single row in just under a minute!

You're forgetting seek latency. It's orders of magnitude better with SSD, but it's still not necessarily zero. Depending on how the data is laid out and queried you can pay the seek cost per row, which multiplied by the number of rows (100GB+) isn't trivial.

uxcn··on C++17 and its Technical Specifications
Exception specifications (deprecated) aren't the same as checked exceptions, which I think was what some people might have in mind. In theory, they look like they solve a number of problems, but in practice they really create more than they solve. Even Java language designers have said that checked exceptions were a mistake.

The noexcept keyword was actually added to address some of the limitations.

uxcn··on Fitt's Law
FItts' Law partly explains why I prefer keyboard oriented interfaces.
uxcn··on C preprocessor tips and tricks
> Any kind of repeating lists (enum + a switch over all the values, for example) are best handled by define-include-undefine sequences.

> See how it is done in LLVM, see all the .def files there. I cannot think of a single viable alternative to this method.

I've seen x-macros. I'm not sure I've seen them used to good effect, but I'd definitely be curious how the llvm code uses them.

> If you want a dense, readable, maintainable code - you're out of options, you have to resort to the preprocessor.

I guess it wasn't entirely obvious from my comment, but I wasn't arguing against using the preprocessor. It's self-contained, mostly usable with common tools, etc.. Anything that's supported on more than one platform or has compile time options generally depends on it. Dense, readable, maintainable code is definitely a good thing, which is one of the reasons I'd personally like to see a usable reflection land in C++.

uxcn··on C preprocessor tips and tricks
You don't have to use the preprocessor, but it is definitely practical for certain things. It's probably not clear from my comment, but macros were what I assumed the above post was talking about though (e.g. min/max). FYI, some projects actually eschew the C/C++ preprocessor for other languages.

I tend to avoid macros, but stuff like generating things at compile time can sometimes be pretty useful. It can make it harder for other people to read the code if they're not familiar with it though (also any tools that need to parse), which is why I try to prefer using UltiSnips for most stuff I normally might do with a macro.

uxcn··on C preprocessor tips and tricks
Also things like generating code at compile time, but a lot of people could argue it both ways.
uxcn··on C preprocessor tips and tricks
In C++, probably never. In C, they can be necessary for doing type orthogonal things (like intrusive data structures). Type generic expressions in C11 can be a bit of a safer alternative for some stuff, but you generally need to give explicit implementations for each type.

For example,

    #define sqrt(x) _Generic((x), long double: sqrtl, float: sqrtf, default: sqrt)(x)
uxcn··on Single address spaces: design flaw or feature?
I think I'd agree, performance probably isn't the most compelling argument for unikernels, but it seems to be the one that's getting the most attention. Even from the performance perspective, eliminating context switches doesn't even seem like the most interesting aspect. The more interesting thing, at least to me, seems to be that a number of virtual mechanisms are implemented in hardware now, which in theory could allow for orders of magnitude reductions in latency (energy consumption).
uxcn··on Single address spaces: design flaw or feature?
Not all system calls imply a context switch either. Linux has had a vDSO mechanism for some time.
uxcn··on Show HN: how2 – stackoverflow.com from the terminal
Text web browsers also make a lot of stuff like this reasonably easy inside a terminal. Someone mentioned http://elinks.or.cz/ a while ago.
uxcn··on What sparked the Cambrian explosion?
Both Cosmoses (Carl Sagan's and Neil deGrasse Tyson's) also give a decent high level overview. The latter is still on Netflix I think.
uxcn··on The IPv6 Numeric IP Format Is a Usability Problem
> This is an issue for network people and developers.

So, the problems mentioned in the post essentially were...

    * ambiguity specifying ports

    * software not recognizing addresses

    * length to type (3-32+7 characters)
Looking past DNS, the first is only really an issue in web browsers, which I would doubt most people will actually use. The second is arguably a software issue, not a format issue. The third genuinely seems marginally debatable. Still, it seems like the amount of code needed to translate from one format to another would be trivial. In the amount of time it took to write the post, someone could probably have just written the code instead. There are tons of plugin mechanisms for stuff (shell, editor, browser, etc...)..

> Given that machines, networks, routes, etc. are all becoming increasingly ephemeral

MPTCP addresses some of these issues.

uxcn··on The IPv6 Numeric IP Format Is a Usability Problem
The majority of people will use IPv6 transparently through DNS. I'm not sure why typing an address into a browser or even a terminal seems like the more common use case.
uxcn··on History of massive-scale sorting experiments at Google
The FAST (FIX Adapted for STreaming) protocol also uses a stop bit encoding. My guess was the data dependencies added to the pipeline would wash out the message size saved on average.
uxcn··on Show HN: Farmhash (C99)
Cityhash successor port to C.
uxcn··on Wasavi – a browser extension that transforms TEXTAREA elements into a VI editor
Nice, it even has a Javascript interpreter. I use w3m for various things, but the lack of Javascript makes it less than usable for a ton of stuff. The lack of configurable key-bindings also makes me sad.
uxcn··on Use Atom to edit in Chrome
The textareas are close, but it's not the same as having the actual editor. I use UltiSnips a lot, which without the actual editor you can't use. It's the same with a lot of Tim Pope's plugins (abolish, surround, etc...).
uxcn··on Use Atom to edit in Chrome
There are python scripts to do this. Adding a mapping to do it in Vim/NeoVim would be fairly straightforward.
← PreviousPage 2 of 10Next →