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

gh-115999: Add free-threaded specialization for COMPARE_OP #126410

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Yhg1s
Copy link
Member

@Yhg1s Yhg1s commented Nov 4, 2024

Add free-threaded specialization for COMPARE_OP, and tests for COMPARE_OP specialization in general. This relies on thread-local bytecode and atomic operations to update the counters and bytecode, which are single operations.

Copy link
Contributor

@mpage mpage left a comment

Choose a reason for hiding this comment

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

LGTM! Please add a short explanation of why the specialized instructions are thread-safe to either the pull request or the commit (when it's merged).

Copy link
Member

@markshannon markshannon left a comment

Choose a reason for hiding this comment

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

The approach looks sound, but the test will need moving and should not rely on specific sequences of instructions.

@@ -1335,6 +1335,32 @@ def test_call_specialize(self):
got = self.get_disassembly(co, adaptive=True)
self.do_disassembly_compare(got, call_quicken)

@cpython_only
Copy link
Member

Choose a reason for hiding this comment

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

Can we move this test to a more appropriate location, like test_opcache?

Also, can we avoid hardcoding sequences of instructions into the tests and use a behavioral approach: testing that the behavior is the same with and without specialization.

We should already have tests for specialization of COMPARE_OP somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

Behavioural tests specifically for specialization sound like a great idea regardless of whether we're free-threaded or not. They should still make sure that actual specialization happened, and not just exercise some code. As far as I can tell we don't have any of those right now. I assume that was on purpose.

I agree we should already have tests for specialization of COMPARE_OP, but we don't. That's why I added the new test, similar to the existing test for specialization of BINARY_OP, which Matt adapted for free-threaded specialization in #123926. That test existed here, in test_dis. I assume they were added here on purpose. Should all those tests be moved to a more appropriate location?

Copy link
Member

@corona10 corona10 Nov 6, 2024

Choose a reason for hiding this comment

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

Please take a look: #126498,
even I am not sure Mark intended these kinds of tests.
(If I add COMPARE_OP tests, it is properly failed.)

@bedevere-app
Copy link

bedevere-app bot commented Nov 6, 2024

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@@ -2393,12 +2394,12 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
goto failure;
}
if (PyFloat_CheckExact(lhs)) {
instr->op.code = COMPARE_OP_FLOAT;
specialized_op = COMPARE_OP_FLOAT;
Copy link
Member

Choose a reason for hiding this comment

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

Now you can use helpers to write it, like specialize(instr, COMPARE_OR_FLOAT) which looks clearer.
(You need to merge main to get changes from 9ce4fa0)

goto success;
}
}
SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
failure:
STAT_INC(COMPARE_OP, failure);
instr->op.code = COMPARE_OP;
SET_OPCODE_OR_RETURN(instr, COMPARE_OP);
Copy link
Member

Choose a reason for hiding this comment

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

The same applies to that piece of code, you can remove both of failure and success blocks, now you just need to do unspecialize(instr, compare_op_fail_kind(lhs, rhs)). And in fact there's no more a SET_OPCODE_OR_RETURN macro :)

Also don't forget to remove the #ifdef Py_STATS directive near the compare_op_fail_kind.

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

Successfully merging this pull request may close these issues.

5 participants