Live data from Hacker News

Optimizing the Particle Life: From 400 to 4M particles

programmingattack.com

31–40 of 71 posts

Re: Optimizing the Particle Life: From 400 to 4M particles

#31
post #4

IMO, not using any optimization flags with C is somewhat arbitrary, since the compiler writers could have just decided that by default we'll do thing X, Y, and Z, and then you'd need to turn them off explicitly. FWIW, without -O, with -O, and with -O4, I get 2500ms, 1500ms, and 550ms respectively. I didn't bother to look at the .S to see the code improvements. (Of course, I edited the code to output the results, othe…

Thanks for posting your results!

Since I was already set on writing in-browser particle life, I didn't benchmark C code with different flags.

Re: Optimizing the Particle Life: From 400 to 4M particles

#32
post #31
post #4

IMO, not using any optimization flags with C is somewhat arbitrary, since the compiler writers could have just decided that by default we'll do thing X, Y, and Z, and then you'd need to turn them off explicitly. FWIW, without -O, with -O, and with -O4, I get 2500ms, 1500ms, and 550ms respectively. I didn't bother to look at the .S to see the code improvements. (Of course, I edited the code to output the results, othe…

Thanks for posting your results! Since I was already set on writing in-browser particle life, I didn't benchmark C code with different flags.

Completely reasonable. I'd probably edit your blog post a bit to indicate that.

Re: Optimizing the Particle Life: From 400 to 4M particles

#33

Earlier quoted context omitted.

It's not rocket science, but "trivial" is very harsh. This stuff is fiddly to get right. The author (who I assume is a student) seems to have done a good job and it's a nice writeup.

I guess you could argue that, but it's strange that people want to give a student's first project (with a lot of huge mistakes like thinking node is going to outperform C because they didn't turn optimizations on) so much interest. I think people are taken in by big numbers and assume there is something cutting edge because they don't know any better. The results are just some particles in an extremely basic pattern,…

One point needs correcting though - nowhere in the article I say that node is outperforming C, on the contrary - I stressed that I didn't use any flags so that people don't come to a conclusion that C would be always slower, and I explicitly mentioned not get fixated on such benchmarks.

What it was meant to show is that V8 is *good enough* to even consider it for the job :)

Re: Optimizing the Particle Life: From 400 to 4M particles

#34
post #4

IMO, not using any optimization flags with C is somewhat arbitrary, since the compiler writers could have just decided that by default we'll do thing X, Y, and Z, and then you'd need to turn them off explicitly. FWIW, without -O, with -O, and with -O4, I get 2500ms, 1500ms, and 550ms respectively. I didn't bother to look at the .S to see the code improvements. (Of course, I edited the code to output the results, othe…

Should also test -Os when doing this sort of thing. Sometimes the reduced size greatly improves cache behavior, and even when not it's often outright competitive with at least -O2 anyway (usually compiles faster too!)

Re: Optimizing the Particle Life: From 400 to 4M particles

#35
post #14
post #6

Earlier quoted context omitted.

Simply compiling it with -O3 produces something which completes in half the time of the JavaScript version (350ms for C, 750ms for JS), so perhaps that. Edit for Twirrim: on this system (Ryzen 7, gcc 11): "-O3": 350ms; "-O3 -march=native": 208ms; "-O2": 998ms; "-O2 -march=native": 1040ms. Edit 2: Interestingly, changing the C from float to double produces a 3.5x speedup, taking the time elapsed (with "-O3 -march=nati…

For fun and frolics: No flags: 1843ms -march=native: 2183 ms -O2: 423 ms -O2 -march=native: 250 ms -O3: 425 ms -O3 -march=native: 255 ms O3 doesn't seem to be helping in my case.

They didn't use any optimization flags.

Re: Optimizing the Particle Life: From 400 to 4M particles

#36
post #30

The thing that strikes me as particularly weird about this is the use of numpy there. In other languages, they're using native code. In python they're reaching out to numpy, which is a great library, but not awesome inside a hot loop unless you're keeping the operation you're carrying out within numpy itself. This means, right in that hot loop, they're doing a lot of translating of numbers between python representati…

This is the problem that Numba was designed to solve.

https://numba.readthedocs.io/en/stable/user/5minguide.html

Re: Optimizing the Particle Life: From 400 to 4M particles

#37
post #10

This is pretty neat... Having an interest in the space for many years (on-and-off; life gets busy sometimes) - I've often lamented the lack of good pixel-level performance optimizations in graphics cards. Everything seems hell-bent on polygons. Some years ago, DirectDraw on Windows was an excellent way to optimize the graphics portion of these types of things, but that all went away as "3D Is The Way" mentality took…

There's no lack of "pixel-level performance optimisations" on GPUs, and just because basically the whole world seems to think that graphics programming == using some rasterisation library like OpenGL or DX or Vulkan or whatever for realtime applications, doesn't mean you're forced to use it or that that's all there is. Just fire up OpenCL (or CUDA, if you must) and start executing some data-parallel kernels.

Is vulkan strictly a rasterization library?

I thought you could also do numeric calculations with compute shaders.

Re: Optimizing the Particle Life: From 400 to 4M particles

#38
post #33

Earlier quoted context omitted.

I guess you could argue that, but it's strange that people want to give a student's first project (with a lot of huge mistakes like thinking node is going to outperform C because they didn't turn optimizations on) so much interest. I think people are taken in by big numbers and assume there is something cutting edge because they don't know any better. The results are just some particles in an extremely basic pattern,…

One point needs correcting though - nowhere in the article I say that node is outperforming C, on the contrary - I stressed that I didn't use any flags so that people don't come to a conclusion that C would be always slower, and I explicitly mentioned not get fixated on such benchmarks. What it was meant to show is that V8 is *good enough* to even consider it for the job :)

You benchmarked three different programs and one was compiled to be slow. Why give times for a debug build when the other two aren't? Showing off performance metrics that are both apples to oranges while also giving times for something not made to run fast is total nonsense.

Do you really not think this is a mistake? Most people would see C getting outperformed and realize there is something wrong. I'm shocked anyone would both this then try to rationalize it after.

Re: Optimizing the Particle Life: From 400 to 4M particles

#39
post #30

The thing that strikes me as particularly weird about this is the use of numpy there. In other languages, they're using native code. In python they're reaching out to numpy, which is a great library, but not awesome inside a hot loop unless you're keeping the operation you're carrying out within numpy itself. This means, right in that hot loop, they're doing a lot of translating of numbers between python representati…

Yeah, an all-numpy version runs in less than 1ms on my M1 air

  import numpy as np
  l = 10_000
  t = np.empty(l, dtype=np.float32)
  j = np.arange(l)
  t = 0.02 \* j
  t *= (0.03 * j)
  t -= (0.04 \* j)
  t /= 0.05 \* (j + 1)

Re: Optimizing the Particle Life: From 400 to 4M particles

#40
post #4

IMO, not using any optimization flags with C is somewhat arbitrary, since the compiler writers could have just decided that by default we'll do thing X, Y, and Z, and then you'd need to turn them off explicitly. FWIW, without -O, with -O, and with -O4, I get 2500ms, 1500ms, and 550ms respectively. I didn't bother to look at the .S to see the code improvements. (Of course, I edited the code to output the results, othe…

One optimization for the C code is to put "f" suffixes on the floating point constants. For example convert this line:

    t[i] += 0.02 * (float)j;
to:

    t[i] += 0.02f * (float)j;
I believe this helps because 0.02 is a double and doing double * float and then converting the result to float can produce a different answer to just doing float * float. The compiler has to do the slow version because that's what you asked for.

Adding the -ffast-math switch appears to make no difference. I'm never sure what -ffast-math does exactly.

Minimal case on Godbolt:

https://godbolt.org/z/W18YsnMY5 - without the f

https://godbolt.org/z/oc1s8WKeG - with the f

Post reply on HN