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

Can someone shed light on these two steps in the approximation?

  *         since cos(x+y) ~ cos(x) - sin(x)*y
  *                        ~ cos(x) - x*y,
For the first, maybe it's an approximate identity I'd never heard of?

For the second, it seems like it relies on X being small, but in this code... Y might be small enough for sin==identity approximation, but X isn't, is it?


The input is a double-double where y << x by definition. So the first line is just using the standard cos identity cos(x+y) = cos(x)cos(y) - sin(x)sin(y). Since y is very small, we can approximate cos(y) ~= 1, and sin(y) ~= y. This yields the first line.

The second line, I believe, is not relying on x being small, but rather relying on sin(x)*y being small. The whole result of the sin(x)*y term is approximately on the order of the LSB of the result, and the relative error of approximating sin(x) using 1 is better than using 0, so this term will help produce more accurate rounding of the bottom bits.


I think the function inputs are in double-double format, so the assumption is that the magnitude of y is significantly smaller than the magnitude of x, ideally |y| < 2^(-52) |x|. So that 1 is a very good approximation for cos(y), since |cos(y) - 1| < |y|^2 < 2^(-104) |x|^2. Similarly, if we assume |x| is also small, |sin(x) - x| < |x|^3 is also a very good approximation (same with sin(y) ~ y).

So using the cosine of sum formula:

  *  cos(x + y) = cos(x) cos(y) - sin(x) sin(y)
  *             ~ cos(x) - x*y.


Looks like angle sum identity.

    cos(x+y) = cos(x)*cos(y) - sin(x)*sin(y)     (always)
             ~ cos(x)*1      - sin(x)*y          (if y small)
Can't speak for the validity of small angle assumptions though.


SongTable won’t compile (on any modern compiler) because the number of initializers (36) doesn’t match the declaration (32)


Hilarious. Yeah, it definitely inferred the wrong thing there. I checked the original code, there is no length define at all. Thus it just inferred the wrong thing.


In addition to the sibling comments, one simple opportunity available to a JIT and not AOT is 100% confidence about the target hardware and its capabilities.

For example AOT compilation often has to account for the possibility that the target machine might not have certain instructions - like SSE/AVX vector ops, and emit both SSE and non-SSE versions of a codepath with, say, a branch to pick the appropriate one dynamically.

Whereas a JIT knows what hardware it's running on - it doesn't have to worry about any other CPUs.


One great example of this was back in the P4 era where Intel hit higher clock speeds at the expense of much higher latency. If you made a binary for just that processor a smart compiler could use the usual tricks to hit very good performance, but that came at the expense of other processors and/or compatibility (one appeal to the AMD Athlon & especially Opteron was that you could just run the same binary faster without caring about any of that[1]). A smart JIT could smooth that considerably but at the time the memory & time constraints were a challenge.

1. The usual caveats about benchmarking what you care about apply, of course. The mix of webish things I worked on and scientists I supported followed this pattern, YMMV.


AOT compilers support this through a technique called function multi-versioning. It's not free and only goes so far, but it isn't reserved to JITs.

The classical reason to use FMV is for SIMD optimizations, fwiw


The first thing to point out is that our implementation isn't pure WASM. We attempted to compile Postgres for WASM directly from source, but it was more complicated that we anticipated.

Crunchy's HN post provided some hints about the approach they took, which was to virtualize a machine in the browser. We pursued this strategy too, settling on v86 which emulates an x86-compatible CPU and hardware in the browser.

I’m out-of-domain but very curious about this part - it seems like a pretty extreme solution with a lot of possible downsides. Does this mean the “just compile native code to WASM” goal is still far off?


The problem is you need operating system features to run Postgres as-is, e.g. mapping memory, forking processes, manipulating files. What is missing is a WASM kernel that skips the x86 emulation but implements enough of the other stuff.

For example, for just one of many hairy problems, consider that Postgres uses global variables in each backend for backend-local state (global state as such is in shared memory). How does this look in assembly, accounting for both the kernel and userspace components? This is the problem.

A general way to convey this is: the more system calls a piece of software uses, the more difficult a WASM target without architecture emulation becomes. And Postgres doesn't even obligate that many obscure ones.


Thanks, those are specific requirements I could definitely see WASM struggling to meet.

In my experience in a large+mature enough codebase (particularly one that is already multi-platform, like Postgres appears to be) many of those requirements are wrapped in an abstraction layer to allow targeting new platforms, but some requirements (like memory mapping) could definitely be dealbreakers if the target platform doesn't naturally support them.

This solution still seems awfully complex (and probably not very efficient) but I certainly see why it's probably the "easiest" option.


I suppose, Postgres is portable, but it's portable to multi-tasking operating systems with virtual memory (which puts in a rather broad category of programs). This goes beyond wrapping how various system calls work on various platforms, but rather changing how accesses are generated, e.g. so backend 1 sees memory location 1 for its global field, backend 2 sees memory location 2 for that same global variable etc. Unlike functions that are frequently wrapped, there is no error code (save ones generated by a processor, e.g. segfault or bus error) or function called for loading an address.

Long story short, I think the need to bypass MMU hardware emulation would prove among the most difficult problems. It will probably require assistance from the compiler, I don't know enough about WASM to guess how mature such relocations would be.


Supabase developer here. I've tried compiling directly to WASM, but it did not go well. As I recall, there were features used by PostgreSQL that WASM didn't support yet. This is definitely something we'll revisit though, especially as WASM matures!


The word expert is not being used in the colloquial sense, but in the technical sense of an "Expert System": https://en.wikipedia.org/wiki/Expert_system


So if I make a new, identical copy of a GPL'ed codebase - should I feel free to use it for whatever purpose I want and ignore the GPL?


The full game isn't playable on that page. I believe all three sets of assets (HLDM, Uplink, Hazard Course) are from demos or free products.

Making the full game playable would probably be less OK.


It's totally reasonable to lament duplicated effort, but it's worth pointing out that this particular attempt is from a company[0] whose business is Qt consulting - so it's easy to imagine that they might succeed (due to expertise, size, and motivation) where others have not.

The post also explains why they started from scratch vs. existing approaches - I'm not qualified to evaluate the claims, but I think they deserve some credit for explicitly talking through their reasons.

[0] https://www.kdab.com/


I think GP is reacting to the word "obligation" (I certainly did.)

I'd claim there are actions that may be "morally justifiable" yet not raise to a level that creates a "moral obligation." The word "obligation" implies (to me at least) some sort of guilt or culpability if you don't undertake the action.

In fact my instinct is that most morally justifiable actions aren't weighty enough to be obligations. Consider any "morally neutral" action (for example, eating an apple instead of an orange for a snack) - I would label such an action "morally justifiable" (since applying the rules of morality does not argue against it) but it's certainly not a "moral obligation" (even ignoring the fact that the alternative is also morally justifiable!)

You could perhaps argue there is no such thing as a "truly neutral" action to an omniscient observer, who can measure and predict the impact on total human happiness of any action with certainty. Such an individual would indeed have a much more restrictive set of "morally justifiable" actions available to them - fortunately we mortals aren't burdened with that level of insight or certainty!


Interesting, I can see something being morally neutral or unknowable, but still don't understand the distinction between moral and moral obligation. If you know an action is moral but you are not doing it, you're acting is implicitly not moral. The only remaining conclusion is admission that do not act in a moral way.

If I understand correctly, your distinction between moral and morally justifiable is just a matter of uncertainty of facts, and if more facts were known, it would become moral or not? Is that correct?


Not GP, but the code in the article passes 'unsigned int mutex' by-value, and then operates on its address (which will potentially be at a different stack address on each invocation, and will certainly be different for different threads.) It won't serve its purpose at all.

To my eye, the code is fundamentally broken in a way that's surprising for an article trying to teach threading, and it's likely confuse someone unfamiliar with these concepts.


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

Search: