Live data from Hacker News

The Prospero Challenge

mattkeeter.com

31–40 of 42 posts

Re: The Prospero Challenge

#31
Can anyone explain where this blob of "assembly language" comes from? In practice, the author presumably with the desired output image and backed into this esoteric format, but I'm not following how.

What is considered an acceptable preprocessing or transformation? In the limit case, a static executable that computes nothing and outputs a constant, literal image probably violates the intention of the question.

Re: The Prospero Challenge

#32

Nice challenge, I got it down to 0.5ms/frame. https://github.com/kevmo314/prospero.vm

So 2000 fps, 16 million pixels, and 7000 operations per pixel, works out to 224 TFLOPS.

An RTX 4090 is advertised as being able to compute 82 TFLOPS.

Where do you think the extra is coming from? Is it just straightforward optimisations like constant folding? Or do you think the compiler is noticing that 1000 iterations of the loop doesn't change the answer and optimising it down to just 1 loop?

Re: The Prospero Challenge

#33

Nice challenge, I got it down to 0.5ms/frame. https://github.com/kevmo314/prospero.vm

So 2000 fps, 16 million pixels, and 7000 operations per pixel, works out to 224 TFLOPS. An RTX 4090 is advertised as being able to compute 82 TFLOPS. Where do you think the extra is coming from? Is it just straightforward optimisations like constant folding? Or do you think the compiler is noticing that 1000 iterations of the loop doesn't change the answer and optimising it down to just 1 loop?

[deleted]

Re: The Prospero Challenge

#34

Can anyone explain where this blob of "assembly language" comes from? In practice, the author presumably with the desired output image and backed into this esoteric format, but I'm not following how. What is considered an acceptable preprocessing or transformation? In the limit case, a static executable that computes nothing and outputs a constant, literal image probably violates the intention of the question.

> In practice, the author presumably with the desired output image and backed into this esoteric format, but I'm not following how.

I actually don't think this is how he did it. You might notice the font is kind of weird.

I think he started with an SDF font and created the "assembly language" from that. https://en.m.wikipedia.org/wiki/Signed_distance_function

Re: The Prospero Challenge

#35

Nice challenge, I got it down to 0.5ms/frame. https://github.com/kevmo314/prospero.vm

So 2000 fps, 16 million pixels, and 7000 operations per pixel, works out to 224 TFLOPS. An RTX 4090 is advertised as being able to compute 82 TFLOPS. Where do you think the extra is coming from? Is it just straightforward optimisations like constant folding? Or do you think the compiler is noticing that 1000 iterations of the loop doesn't change the answer and optimising it down to just 1 loop?

It’s a good question, admittedly I don’t know. I looked into it when Matt mentioned it but I’m not so familiar with what happens after ptx to say.

If someone does know I’d love to learn why though.

Re: The Prospero Challenge

#36

Can anyone explain where this blob of "assembly language" comes from? In practice, the author presumably with the desired output image and backed into this esoteric format, but I'm not following how. What is considered an acceptable preprocessing or transformation? In the limit case, a static executable that computes nothing and outputs a constant, literal image probably violates the intention of the question.

> Can anyone explain where this blob of "assembly language" comes from?

Assembly language is definitely the right analogy: it's a low-level target generated by higher-level tools. In this case, the expression came from a Python script calling this text(...) function:

https://github.com/mkeeter/antimony/blob/f6a56dd7/py/fab/sha...

The font is hand-built from geometric primitives (rectangles, circles, etc) and CSG operations (union, intersection, difference)

> What is considered an acceptable preprocessing or transformation?

I'm looking for interesting ideas, and to mine the depths of PLs / compiler / interpreter / runtime research. Just returning a fixed image isn't particularly interesting, but (for example) I just updated the site with a compile-to-CUDA example that shows off the brute force power of a modern GPU.

Re: The Prospero Challenge

#37

Nice challenge, I got it down to 0.5ms/frame. https://github.com/kevmo314/prospero.vm

So 2000 fps, 16 million pixels, and 7000 operations per pixel, works out to 224 TFLOPS. An RTX 4090 is advertised as being able to compute 82 TFLOPS. Where do you think the extra is coming from? Is it just straightforward optimisations like constant folding? Or do you think the compiler is noticing that 1000 iterations of the loop doesn't change the answer and optimising it down to just 1 loop?

Pretty sure it's optimisations.

Even small things like converting multiplications followed by additions to FMA will reduce the operation count.

Add to that constant folding etc. and a speedup factor of ~3 is not so hard to imagine.

Re: The Prospero Challenge

#38
post #36

Can anyone explain where this blob of "assembly language" comes from? In practice, the author presumably with the desired output image and backed into this esoteric format, but I'm not following how. What is considered an acceptable preprocessing or transformation? In the limit case, a static executable that computes nothing and outputs a constant, literal image probably violates the intention of the question.

> Can anyone explain where this blob of "assembly language" comes from? Assembly language is definitely the right analogy: it's a low-level target generated by higher-level tools. In this case, the expression came from a Python script calling this text(...) function: https://github.com/mkeeter/antimony/blob/f6a56dd7/py/fab/sha... The font is hand-built from geometric primitives (rectangles, circles, etc) and CSG oper…

What are the practical implications of this kind of assembly language? Surely there’s more efficient means of describing 2D SDFs?

Fun exercise! I’ve been enjoying trying to find some new ways to approach the challenge. I managed to build a single string expression for the entire program, so it could be evaluated per-pixel in a shader, but it turns out the expression is too complex for WebGL & WebGPU and the shader fails to compile.

My next thought would be to evaluate the program at a low resolution to create a low res SDF texture for the shader to draw at a higher resolution. Some information will probably be lost, though.

Re: The Prospero Challenge

#39
post #36

Earlier quoted context omitted.

> Can anyone explain where this blob of "assembly language" comes from? Assembly language is definitely the right analogy: it's a low-level target generated by higher-level tools. In this case, the expression came from a Python script calling this text(...) function: https://github.com/mkeeter/antimony/blob/f6a56dd7/py/fab/sha... The font is hand-built from geometric primitives (rectangles, circles, etc) and CSG oper…

What are the practical implications of this kind of assembly language? Surely there’s more efficient means of describing 2D SDFs? Fun exercise! I’ve been enjoying trying to find some new ways to approach the challenge. I managed to build a single string expression for the entire program, so it could be evaluated per-pixel in a shader, but it turns out the expression is too complex for WebGL & WebGPU and the shader fa…

> What are the practical implications of this kind of assembly language? Surely there’s more efficient means of describing 2D SDFs?

By analogy, you wouldn't program in LLVM IR, but it's a useful intermediate representation for a bunch of higher-level languages. Higher-level tools can target this representation, and then they all get to use a standard set of optimizations and algorithms (fast evaluation, rendering, etc).

(I gave a recent talk that's a broad overview of this research: https://www.youtube.com/watch?v=UxGxsGnbyJ4)

> My next thought would be to evaluate the program at a low resolution to create a low res SDF texture for the shader to draw at a higher resolution.

Glad you're enjoying the challenge! You may also be interested in

https://www.redblobgames.com/x/2403-distance-field-fonts/

Re: The Prospero Challenge

#40

Earlier quoted context omitted.

So 2000 fps, 16 million pixels, and 7000 operations per pixel, works out to 224 TFLOPS. An RTX 4090 is advertised as being able to compute 82 TFLOPS. Where do you think the extra is coming from? Is it just straightforward optimisations like constant folding? Or do you think the compiler is noticing that 1000 iterations of the loop doesn't change the answer and optimising it down to just 1 loop?

Pretty sure it's optimisations. Even small things like converting multiplications followed by additions to FMA will reduce the operation count. Add to that constant folding etc. and a speedup factor of ~3 is not so hard to imagine.

I compiled it for Ampere and counted 6834 actual F32 operations in the SASS after optimizations. I only counted FFMA, FADD, FMUL, FMNMX, and MUFU.RSQ after eyeballing the SASS code, so there might even be more. It's possible the FMNMX doesn't actually take a FLOP since you can do f32 max as an integer operation, and perhaps MUFU.RSQ doesn't either, but even if you only count FFMA, FADD, and FMUL there are still 3685 ops.

  nvcc -arch=sm_86 prospero.cu -o prospero
  cuobjdump -sass prospero | grep -E 'FFMA|FADD|FMUL|FMNMX|MUFU\.RSQ' | wc -l
Post reply on HN