HNHacker News
TopNewBestAskShowJobs

fluffything

2,917 karma · joined April 21, 2019

submissionscomments
fluffything··on Let's guess what Google requires in 14 days or they kill our extension
> I installed Firefox and deleted Chrome

You know that Firefox is Google right? Like, literally, Google is the main company paying Firefox's developers, and if they don't do what Google says, Google can just cut the funding, and they all end up unemployed, right ? Of course, to avoid a monopoly, Google would need to fund a different browser instead, but still, people have families to feed.

If you want to cut dependencies on Google, Firefox is not the answer, and neither is Tor or any other Firefox derived web-browser.

fluffything··on A first look at Unreal Engine 5
From the video it sounded to me that the 100s billions of triangles were from single instance geometry. The models they mention in the video are in the ball park of >1 billion triangles each (that's 12 Gb per model). So if they have 100 models of that resolution, that's 12 Tbs, and whether they instance each model 1 or 100 times doesn't matter much because the problem of having to fit those 12 Tb in triangles somewhere still remains.

That's why it seems much more plausible to me that they are not storing triangles anywhere, and instead just storing geometry images.

fluffything··on A first look at Unreal Engine 5
In the video they mention that the "heavy geometry" you are talking about is 100s of billions of triangles. Storing 1 billion triangles using 32-bit floats takes ~12 Gb, so we are talking about N * 12 Tbs only in triangle storage for this demo. Building an acceleration data-structure on top of this would also take up a lot of storage, so I don't think how you can make this approach successful on a PS5 with limited GPU memory.

To me this tech sounds more like they finally figured out all the quirks around how to properly construct "seamless geometry atlasses" (geometry images) and reconstruct geometry from them, and managed to bring that to production. It required quite a bit of compute, and there were also a lot of quirks about how to automatically "cut" an input geometry so that you can put it in a 2D image, how to compress and decompress the image or parts of it without artifacts (such that you don't get jumps across triangles), etc.

That approach doesn't store any triangles, but a 2D xyz (rgb) image that you can use to reconstruct the original geometry from, and to which you can apply all usual image compression algorithms, use all GPU texture features (but for geometry), etc.

That's ~15 year old tech, and they mention they have been working on this for over 10 years, so timeline-wise it would fit (search for geometry images, texture atlasses, etc. there was a siggraph talk from ~2005 about wavelet compression of geometry images).

fluffything··on RISC-V OS using Rust: Filesystems
Yeah, I was thinking more about what to do with the OS afterwards. That board has lots of things on it, including wifi, so I'll probably would like to use some of that.

It would be unfortunate to have to re-implement the wifi driver in Rust, but I suppose I'll just have to link parts of the C toolchain instead, creating Rust wrappers, etc.

fluffything··on Janet: a lightweight, expressive and modern Lisp
The user above mentioned that for _them_ the installation experience of a programming language matters a lot, and that they found the installation experience of Janet superior to Clojure.

You might not share that users preference of caring about the installation experience of a PL, but arguing that this user's preference is somehow unfair because many other languages also have bad installation experiences makes absolutely no sense.

fluffything··on Apple unveils biggest update to Logic since the launch of Logic Pro X
That's reading too much into the lines. Apple wanted to guarantee that a central piece of software for Mac's marketing success was under their control. Maintaining a Windows version of that software adds no value to Apple's users, so they stopped developing it.

From there to "Apple bought Logic to lock people to Macs" there is a huge leap of faith. The majority of Mac uses do not use Logic, so if their goal was to lock their users to their ecosystem, this move makes no sense.

Also, there are good and often better alternatives to Logic, including Cubase, which work on all major platforms. So if you don't want to move to a Mac from Windows or Linux for the next Logic version, you have many good options.

fluffything··on RISC-V OS using Rust: Filesystems
> I think perhaps a lot of projects start out using nightly with the assumption that within 6-12 months those features they are using will be in stable.

In my experience, that is rarely the case.

People mostly use nightly features because they just need to get something done, and these features make that easier.

The tooling around Rust is quite good (rustup, cargo, docker), so if you follow the language a bit, judge which nightly features you opt-into, pin nightly version in your build environment, etc. breakage only happens when you actually have time to fix it and the fixes are simple.

So the bar for how much easier a nightly feature needs to make your problem to overcome its costs is quite low. The moment you are using one nightly feature, the cost of using more is even smaller.

fluffything··on RISC-V OS using Rust: Filesystems
I was looking at getting this Maixduino kit since it appears to be the cheapest solution that satisfies my constraints (RISCV core + WiFi):

https://www.seeedstudio.com/Sipeed-Maixduino-Kit-for-RISC-V-...

I'm not sure what's the status of programming these from Rust. I suppose that you will probably need to build your own toolchain that links the Seeedstudio libraries.

fluffything··on RISC-V OS using Rust: Filesystems
This is awesome. I've been following along for a while, so please keep it up.

I wish someday we'll get something like the ESP32 boards but with RISCV.

fluffything··on Make LLVM Fast Again
Accepting a performance loss is almost always the right trade-off. If it weren't, everybody would be writting their code in assembly at 5LOC/day.
fluffything··on Make LLVM Fast Again
What would you expect to learn and how would you do this?

I can't imagine anything useful coming out of it.

fluffything··on Elon Musk reopening Tesla factory despite Alameda County order
Good point, thanks.
fluffything··on Make LLVM Fast Again
Ah right, for some reason I thought you were talking about C++.

Yes for C what you mention makes perfect sense.

I agree with you about C++ as well. In particular, C++ templates end up expanding a lot of duplicate code, and at O1 the compiler can remove them.

fluffything··on Elon Musk reopening Tesla factory despite Alameda County order
> A Tesla factory is a much safer place

Citation needed please.

Tesla's factories are the most dangerous car factories in the US by an order of magnitude more __than all other car manufacturers combined [0]__.

With such a bad safety track record, they must be completely high to believe that they are going to be doing significantly better with a pandemic going on.

Right now, not only the safety of their workers is at stake, but also the safety of the whole region around their factories.

Their track record proves that they cannot be trusted with the safety of their workers, what makes anybody believe that they can be trusted with the safety of whole regions instead?

Doesn't make any sense to me.

[0] https://www.forbes.com/sites/alanohnsman/2019/03/01/tesla-sa...

fluffything··on Make LLVM Fast Again
You can already spend as much as you'd like on optimizations if you are using LLVM. Just use a superoptimizer [0]:

    clang -Xclang -load -Xclang libsouperPass.so -mllvm -z3-path=/usr/bin/z3
, or increase the inlining heuristics..., or just create your own optimization strategy like rustc does [1], or...

LLVM is super configurable, so you can make it do whatever you want.

Clang defaults are tuned for the optimizations that give you the most bang for the time you put in, while still being able to compile a Web browser like Chrome or Firefox, or a whole Linux distribution packages, in a reasonable amount of time.

If you don't care about how long compile-times take, then you are not a "target" clang user, but you can just pass clang extra arguments like those mentioned above, or even fork it to add your own -Oeternity option that takes in your project and tries to compile it for a millenia on a super computer for that little extra 0.00001% reduction in code size, at best.

Because often, code compiled with -O3 is slower than code compiled with -O2. Because "more optimizations" do not necessarily mean "faster code" like you seem tobe suggesting.

[0]: https://github.com/google/souper [1]: https://github.com/rust-lang/rust/blob/master/src/rustllvm/P...

fluffything··on Make LLVM Fast Again
You might have an interesting project, for all my C++ projects, -O1 is significantly faster than -O0 (~2x faster).

Or maybe my projects are the interesting ones :D

fluffything··on Make LLVM Fast Again
If that's the case, an optimized build with clang is also often faster than a debug build with... clang itself.

The reason is that many of the optimization passes that run first, like dead code elimination, can remove a lot of code early on, so "optimized" builds end up processing significantly less code, which is inherently faster.

The OP might just not be aware of what a "debug build" is. The goal of a debug build is for the binary to execute your code as closely to how you wrote it as possible, so that you can easily debug it.

Their goal isn't "fast compile-times". If you want fast compile-times, try using -O1. At that level, both clang and gcc do optimizations that are known to be cheap and remove a lot of code, which speeds up compile-times significantly. Another trick to speed-up compile-times is to use -g0, and if you do not need exceptions, use -fno-exceptions, since those make the front-end emit much less data, which results in less data having to be processed by the backends.

fluffything··on Make LLVM Fast Again
I really hope this type of infrastructure gets moved into LLVM itself, and people start adding more benchmarks for all the frontends, and somehow integrating this into the CI infrastructure, to be able to block merging PRs on changes that accidentally impact LLVM's performance, like is currently the case for rustc.

But I guess the LLVM project should probably start by making code-reviews mandatory, gating PRs on passing tests so that master doesn't get broken all the time, etc. I really hate it when I update my LLVM locally from git master, and it won't even build because somebody pushed to master without even testing that their changes compile...

For Rust, I hope Cranelift really takes off someday, and we can start to completely ditch LLVM and make it opt-in, only for those cases in which you are willing to trade-off huge compile-times for that last 1% run-time reduction.

fluffything··on Making Emacs Popular Again
As others have mentioned:

* $$2^n$$ for latex, renders fine on all browsers

* ![]() for images

* []() for links, including cross-links

    ** The link syntax is [<text to link>](<link path>), so for example [this is a link](http://google.com)

    ** Markdown ## Headers have an anchor with their name (e.g. `#Headers`), so you can cross-reference any other 
    section of any other note in the git repo by just using [see this section](./path/to/other/note.md#that-section)
I have a simple CI service on my git repo that checks for broken links, so that if I move a file I get a CI error if there are broken links to it.
fluffything··on Intel accused by workers of prioritizing chip output over safety
Are you going to take legal action?
fluffything··on Show HN: Micro-mitten – Research language with compile-time memory management
There is a Rust tool that computes the maximum stack usage of a program (if such maximum is bound). You can use it to make sure that your microcontroller running Rust doesn't run out of stack space.
fluffything··on Show HN: Micro-mitten – Research language with compile-time memory management
> I imagine

No need to image, the thesis mentioned in the README provides compile-time results. From no noticeable overhead to 2x larger compile-times than Rust.

Quite reasonable if you take into account that one is one person's university thesis, and the other is a project with 100s of active developers, 100s of open PRs, etc.

fluffything··on Making Emacs Popular Again
I'm a researcher, and I have a git repository for my notes, which I edit using markdown. It supports latex math, tables, cross links, labels, and html if I need to do anything fancy, like inserting images, videos, etc. (youtube embedded video? no problem). I can edit them from any device, and they get sync'ed everywhere via git.

I can also read them from everywhere, and markdown renders super nicely.

I take markdown over org-mode everyday. I used to use org-mode 15 years ago, but today that's pointless for me.

fluffything··on Making Emacs Popular Again
You nailed it.

I'd also add:

- incredibly ergonomic file-system navigation (helm+projectile)

First thing I notice when I use VS Code is... Do I really have to click and click and click and click to navigate from one file to another? Why does VS Code show pop ups all over the place?

I really like how I can navigate the file system from emacs using fuzzy searches when I need them, and how the same fuzzy-search approach helps me also navigate all my buffers, works remotely over tramp, etc.

fluffything··on When Parallel: Pull, Don't Push
> If you can't keep 3 rows of the input matrix in cache, why would you be able to keep 3 rows of the output matrix in cache? If the matrices are large enough that they don't fit in cache, shouldn't they be processed in squareish blocks recursively to maximize cache reuse (not in rows)?

Your cache size is fixed by the computer and you can't change it. If you are doing a convolution, you want "(N+1)xN = cache size" to determine the size of the "blocks" (NxN matrix, and an 1xN row) of the convolution you process. Those blocks are also matrices, so by decomposing your matrix into smaller matrices you don't avoid this problem.

So sure, you could also decompose your problem by doing "(N+3)xN = cache-size", but that means that the size of the "square blocks" that you can now properly fit in cache is smaller, and need to decompose your original problem into more sub-problems to get it done. You could also do: "2Nx2N = cache size", and just load a whole input block and an output block into cache.

In both cases, you are bringing memory into cache that you only touch once, yet continue occupying cache space after you don't need them anymore. You could have used that space to process larger matrices instead, and have to decompose your problem into fewer blocks.

fluffything··on Rosetta: The Engine Behind Cray’s Slingshot Exascale-Era Interconnect
> On many-GPU machines, the CPU isn't idle- it's handling the data infeed and data outfeed pipelines. This can often be a bottleneck if training is really fast and you need to stream lots of examples/sec.

This depends on both the application and the actual machine. Moving data from storage or from the network to the CPU to then feed it to the GPU just increases latency. Unless you are doing some non-parallelizable pre-processing of the data in the CPU, you are often better off with doing DMA or RDMA directly to the GPU memory, fully bypassing the CPU.

Not all machines support that, and not all applications support that either, but many applications do. Arguably, even for the applications that do this, leaving the CPUs unused is not really a desirable property. I've seen a couple of applications that split the compute workload to the CPU to fully utilize the CPU as well, and I've also seem other applications that once the GPU finishes processing they move the data to the CPU memory to leave space on the GPU for the next batch as quickly as possible, and the CPU then streams the data off the node while the GPU continues to compute (so you get an RDMA->GPU->CPU->Storage/Network loop).

> see https://www.nextplatform.com/2018/05/10/tearing-apart-google.... for some speculation on the details.

Thanks for the link, I never learned much about this part of the system.

fluffything··on When Parallel: Pull, Don't Push
The problem it solves is temporal cache locality, and whether pull or push is better often only depends on what is it that you want to keep in cache for the next operation.

For example, suppose you are doing a 3x3 convolution over a matrix, and you want to keep the result of the convolution in cache because the next operation consumes it.

So your cache is pretty much filled with the output matrix, and you only have space in cache to pull in one row from global memory for reading.

Now consider what happens if you process your input matrix row-by-row, first with the pull approach and then with the push approach.

With the pull approach you need to load 3 rows from memory into cache before you can push. No matter how you do this, as you advance through the input, you are going to be loading some rows twice. For example, suppose that from the 3x3 window, we load the rows in this order: top, bottom, mid (and then push the convolution to the mid row of the output). In one iteration we load rows 0, 2 (evicts row 0) and 1 (evicts row 2). The next iteration loads 1 (hit) and 3 (evicts 1), and then 2 (reloads 2!). That's bad!

With the push approach, you load one row, and push partial contributions to the 3 rows of the output matrix. Then you load the next row, and do the same. The output matrix is always in cache, so those writes always hit, and you never need to load a row from memory twice.

So in a sense, pull optimizes for bringing the rows of the output into cache once, which is good if you want to continue working with the input afterwards, while push optimizes for keeping the output in cache, which is good if you want to continue working with the output afterwards.

One isn't really better than the other. Which one to choose depends on what is it that you want to do. Maybe you have one input matrix, and multiple convolution windows, and want to compute multiple outputs that you don't need right away. In that case, you want to keep the input matrix in cache, and compute the rows of the output one by one, evicting them from the cache after each computation.

fluffything··on When Parallel: Pull, Don't Push
That makes perfect sense, and it appears that you always have the option to handrol something if you discover it as a bottle neck worth fixing.
fluffything··on When Parallel: Pull, Don't Push
Which languages are you using?

In my experience, the main problem with expressing your algorithms in that way is "What do you do when the primitives you are suing (e.g. maps and scans) do not produce optimal code?".

For example, suppose that you are doing two scans with two maps, whose efficient implementation does a single memory traversal with the two scans and maps fused into a single kernel. If whatever abstraction you are using isn't able to do this type of kernel fusion, then you easily bump to a 4x larger memory bandwidth, which might be translated to 4x slower performance.

I don't know of any language or optimizing runtime that's able to do these transformations and match the performance of the CUDA code one would have written by hand.

fluffything··on When Parallel: Pull, Don't Push
> If we’re using concurrency, that means multiple threads of execution may be mutating the same cell, which requires synchronization — locks, atomics, etc. That much synchronization is the death knell of performance.

You can do this without synchronization by exploiting the fact that all "lanes" of a SIMD vector execute simultaneously, e.g. by doing vector scatters "to the left" and then "to the right" those writes will not race with each other, and don't require locks or atomics.

Whether pull or push is faster heavily depends on the algorithm - there is no silver bullet here. To write efficient parallel algorithms you need to know how to do both.

The author only appears to know how to do pull (if that's wrong, they didn't really do push any justice in the article), so from their POV push just doesn't work.

The article does show something very important though: pull does give you reasonable performance and is quite easy to reason about and get right. In contrast, push is quite hard due to the write-write data-races the author mentions, so I don't blame the author from arriving at their conclusion that one should always do pull. It might not always be true, but it is definitely a safe place to start, particularly if you aren't super familiar with the algorithm yet and don't know how or if push would work well.

For example, many of the convolutions that neural networks use are actually implemented using the "push" approach because that's more efficient, and they are quite similar to what the blog post author is doing.

← PreviousPage 16 of 31Next →