lovr icon indicating copy to clipboard operation
lovr copied to clipboard

Support table vector

Open xiejiangzhi opened this issue 1 year ago • 1 comments

A simple test https://gist.github.com/xiejiangzhi/856d3a8b97df84ddd7b85b700284a4e7

In this test, by simply drawing a 40K sphere, the FPS of lua table will be increased by 29% compared to using lovr vector. Since there are basically no calculations, if there are more calculations, the gap will be larger. While it would be faster to use numbers directly, using numeric arguments is too much. table will be faster and easier to use and expand

xiejiangzhi avatar Feb 04 '24 05:02 xiejiangzhi

Compared with the slow calling performance of Lua C API, GC of these tables is obviously faster

xiejiangzhi avatar Feb 04 '24 05:02 xiejiangzhi

I did a quick test of this branch on Josip's IK test

LuaJIT:

  • Userdata: 83FPS
  • Table: 109FPS
  • Userdata (jit.off): 80FPS
  • Table (jit.off): 97FPS

Vanilla Lua:

  • Userdata: 76FPS
  • Table: 43FPS

The table library I was using didn't use mutation, so it was creating lots of temporary objects.

bjornbytes avatar Feb 08 '24 20:02 bjornbytes

Can you give me a copy of the test code? Looking at your results on table, ~is the FPS of jit.off higher than the FPS of jit mode?~ I'm dizzy, I actually think 97 FPS is better than 109 FPS.

xiejiangzhi avatar Feb 09 '24 01:02 xiejiangzhi

The table library I was using didn't use mutation, so it was creating lots of temporary objects.

I don't understand what you mean by mutation. If it refers to vec3:add in the lovr vector that directly changes itself, but if it does directly create a table during the Lua test, this test is basically meaningless. Because their underlying logic is different.

xiejiangzhi avatar Feb 09 '24 01:02 xiejiangzhi

On the other hand, I think table support should only require making sure that this feature is useful. I even think it should be supported even if it does not have better performance in all aspects. Using table is obviously easier to expand than using userdata. And my test examples can at least show that its performance is very good in some situations.

Then, I also hope to provide a test code that proves your test results.

xiejiangzhi avatar Feb 09 '24 01:02 xiejiangzhi

https://gist.github.com/xiejiangzhi/856d3a8b97df84ddd7b85b700284a4e7

I have updated my test and completed the test under jit.off. If jit is not turned off, the optimization of jit will make the performance of each Lua table much faster than userdata.

There are the following test modes and results:

name FPS desc
vec3_add_vec3 30 vec3:add(vec3(x, y, z))
vec3_tmp 29 vec3 + vec3(x, y, z)
vec3 34 vec3:add(x, y, z)
table 30 table:add({x, y, z})
table tmp 23 table_vec + { x, y, z}
table_num 40 table:add(x, y, z)

As above, without jit optimization, if you use table_tmp to compare with userdata, it is obvious that userdata has higher performance because table will create more temporary objects. But such FPS comparison is meaningless because their logic is different. Only userdata can be given. The performance is basically the same no matter how it is used. However, when table is used improperly, the performance may not be as good as userdata.

Since my code is relatively simple in the above method, after JIT optimization, the table performance of any method is almost the same at 62FPS. After userdata adds calculations, the performance comparison has dropped to 32FPS. At this time, table performance is already twice that of userdata.

xiejiangzhi avatar Feb 09 '24 02:02 xiejiangzhi

The IK test is attached, but probably bjorn adapted the FPS measurements. The file names come from the branch names: the dev is the currently used vector library, while vec_experiments is non-mutating variant which requires different Lua code.

ik_vec_experiments.zip ik_dev.zip

jmiskovic avatar Feb 09 '24 10:02 jmiskovic

Yesterday, I misunderstood "it was creating lots of temporary objects." to mean that the table is slower, and then I also regarded FPS as being as low as possible. Please ignore some of the more confusing words.

xiejiangzhi avatar Feb 09 '24 21:02 xiejiangzhi

Then it's great to see Josip's IK test getting a performance boost as well

xiejiangzhi avatar Feb 09 '24 21:02 xiejiangzhi

The IK test is attached, but probably bjorn adapted the FPS measurements. The file names come from the branch names: the dev is the currently used vector library, while vec_experiments is non-mutating variant which requires different Lua code.

ik_vec_experiments.zip ik_dev.zip

Thanks, this is only the lovr userdata version. It takes too much time to create the corresponding table version library, so I am too lazy to do it. . .

xiejiangzhi avatar Feb 10 '24 00:02 xiejiangzhi

ik-table.zip

Here's the table version of the IK test. I tested this on this branch rebased onto vector-experiments, and also fixed luax_checkendpoints on this branch to work with tables so the capsules rendered.

On LuaJIT in release mode, I'm getting 42 FPS for tables and 72 FPS for userdata. lovr.update takes about 3ms for userdata and 14ms for tables. lovr.draw takes about 8ms for both.

On vanilla Lua, tables are 15 FPS and userdata are also 72 FPS.

I haven't looked into the performance more deeply yet. Also tvec.lua probably has some bugs.

bjornbytes avatar Feb 17 '24 20:02 bjornbytes

I won't be merging this as-is because I think supporting both userdata and tables at the same time makes things too difficult to document with the combinatorial explosion of function variants.

I'm still interested in switching vectors over to use tables. Tables allow people to implement vectors in Lua and pass them to LÖVR functions, which makes it easier to use their own vector library. Also, in certain cases using tables for vectors will make it easier for LuaJIT to JIT-compile code and can avoid C method call overhead.

The earlier experiments we did are promising. On LuaJIT, userdata and tables have similar performance, especially when using a vector pool. On Lua 5.1 tables are slower, but this isn't a dealbreaker.

Something I still want to think/experiment about is whether it makes sense to keep Mat4 implemented as a userdata object and only switch vectors over to tables. Mat4 holds more values than the other objects which can be slow to read using Lua's C API, and matrix operations involve more number-crunching, so doing that in C might make more sense.

bjornbytes avatar Apr 19 '24 23:04 bjornbytes