Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 2-component vector constructor #1569

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

petrihakkinen
Copy link
Contributor

Implement RFC: 2-component vector constructor. This includes 2-component overload for vector.create and associated fastcall function, and its type definition. These features are controlled by a new feature flag LuauVector2Constructor. Additionally constant folding now supports two components when LuauVector2Constants feature flag is set.

Note: this work does not include changes to CodeGen. Thus calls to vector.create with only two arguments are not natively compiled currently. This is left for future work.

Comment on lines 523 to 530
if (FFlag::LuauVector2Constructor && !vectorSrc.empty())
{
std::string what = "create: @checked (x: number, y: number, z: number) -> vector";
std::string replacement = "create: @checked (x: number, y: number, z: number?) -> vector";
std::string::size_type pos = vectorSrc.find(what);
LUAU_ASSERT(pos != std::string::npos);
vectorSrc.replace(pos, what.size(), replacement);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies that after unflagging, the code will forever do a string substitution of an incorrect definition.
Instead, the code should switch the whole definition string so that after flag is removed we only have one simple definition with no runtime fixups.

@@ -1055,25 +1057,25 @@ static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, St

static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation looks worrying, I would like to see benchmarks on the most common 3 component case it was focused before in LUA_VECTOR_SIZE 3. 3/4 for LUA_VECTOR_SIZE 4 as a bonus.

It also includes many unflagged changes.
As a suggestion for flagging this, consider having if (flag){ full new implementation } else { full old implementation }

LOADK R0 K0 [1, 2, 3]
RETURN R0 1
)");

CHECK_EQ("\n" + compileFunction("print(Vector3.new(1, 2, 3))", 0, 2, 0, /*enableVectors*/ true), R"(
CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3))", 0, 2, 0, /*enableVectors*/ true), R"(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having 'enableVectors' set doesn't actually make sense for a vector.create test.

I would leave at least one test for legacy constructors, but we did want to update some tests to vector.create without enableVectors now that library is available.

@petrihakkinen
Copy link
Contributor Author

petrihakkinen commented Dec 17, 2024

Thanks for the comments. Pushed a revision that addresses all the points mentioned.

Also added a new micro benchmark for vector library. Test results:

LuauVector2Constructor false:

Test Min Average StdDev% Driver
vector: create 71.122ms 72.708ms 1.727% luau.exe

LuauVector2Constructor true:

Test Min Average StdDev% Driver
vector: create 71.517ms 73.315ms 1.447% luau.exe

Command line used:
python bench.py --folder micro_tests --run-test test_vector_lib --extra-loops 50

Tested on: Windows 10, MSVC 2022, Intel i5-3570K

The difference is a bit less than 1% in favor of the old version. I don't think this will make a big difference in practice though.

I also ran the test with only two arguments (the new LuauVector2Constructor path):

Test Min Average StdDev% Driver
vector: create2 51.412ms 52.479ms 1.487% luau.exe

Creating vectors from two components is now much faster as expected (previously ~218ms on average with a user defined 2D constructor without the fastcall).

An idea for future work: we could consider adding a new built-in for the 2D case (luauF_vector2). This would get rid of the extra branch in luauF_vector and get back that 1% and make luauF_vector2 even faster. This would require detecting the number of arguments in the compiler and choosing the correct builtin. Not sure if it makes sense to add complexity for such a small gain though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants