bpo-45367: Specialize BINARY_MULTIPLY#28727
Conversation
|
🤖 New build scheduled with the buildbot fleet by @sweeneyde for commit 300a0ca 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
Sorry, something went wrong.
|
The failing |
Sorry, something went wrong.
|
On and on |
Sorry, something went wrong.
|
Looks promising. Apologies for the merge conflicts from #28723. |
Sorry, something went wrong.
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Thanks Dennis, this looks good and I think it's almost ready to merge :). Just needs some stable benchmarks on non-Windows platforms.
Sorry, something went wrong.
|
It does show speedups for the benchmarks we would expect, but there are significant slowdowns for some other benchmarks; notably the pickle benchmarks. |
Sorry, something went wrong.
|
I've personally disregarded anything from pyperformance in the range of +-1.05x. That said, I wholly believe nbody sped up, I just don't trust pickle slowing down. There's no |
Sorry, something went wrong.
|
I ran I'm guessing specializing int/float mixtures would be beneficial. I wonder if it's better to have a single slightly-more-complex opcode or add more opcodes. I was thinking something like TARGET(BINARY_MULTIPLY_FLOAT) {
PyObject *left = SECOND();
PyObject *right = TOP();
double dleft, dright;
if (PyFloat_CheckExact(left)) {
dleft = ((PyFloatObject *)left)->ob_fval;
if (PyFloat_CheckExact(right)) {
dright = ((PyFloatObject *)right)->ob_fval;
}
else if (PyLong_CheckExact(right) && IS_MEDIUM_VALUE(right)) {
dright = (double)medium_value(right);
}
else {
DEOPT_IF(1, BINARY_MULTIPLY);
}
}
else if (PyLong_CheckExact(left) && IS_MEDIUM_VALUE(left)) {
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_MULTIPLY);
dleft = (double)medium_value(left);
dright = ((PyFloatObject *)right)->ob_fval;
}
else {
DEOPT_IF(1, BINARY_MULTIPLY);
}
STAT_INC(BINARY_MULTIPLY, hit);
record_hit_inline(next_instr, oparg);
PyObject *prod = PyFloat_FromDouble(dleft * dright);
SET_SECOND(prod);
Py_DECREF(right);
Py_DECREF(left);
STACK_SHRINK(1);
if (prod == NULL) {
goto error;
}
DISPATCH();
} |
Sorry, something went wrong.
|
The most recent change gets the results of |
Sorry, something went wrong.
|
What types are you specializing for, and why? Please read https://github.com/python/cpython/blob/main/Python/adaptive.md, specifically https://github.com/python/cpython/blob/main/Python/adaptive.md#gathering-data |
Sorry, something went wrong.
|
My thinking was that two To clarify, are you advising that the increased complexity of the opcode is not worth the increased percentage of instructions specialized? Is the solution to
I am struggling to run the whole pyperformance suite at once, but as an example, bm_spectral_norm goes from to when incorporating I suppose we could gather specialization stats for what happens if |
Sorry, something went wrong.
|
nbody sped up, everything else looks in the realm of noise for pyperformance: https://gist.github.com/Fidget-Spinner/6fd3149fc82497d028b02046765ba8d8 |
Sorry, something went wrong.
Yes.
I don't think there is sufficient evidence that these are useful. At least, not yet.
The deferred operations only represent about 1%. Not worth worrying about. |
Sorry, something went wrong.
|
In general, it is not the number of branches that matters, as much as their predictability. |
Sorry, something went wrong.
|
I am beginning to think this PR may not be worth it at all: even on microbenchmarks, after PGO, there's not that much benefit: Program: from pyperf import Runner
runner = Runner()
runner.timeit(
"int: x*x",
setup="from itertools import repeat; it = repeat(1, 1_000_000)",
stmt="for x in it: x*x")
runner.timeit(
"float: x*x",
setup="from itertools import repeat; it = repeat(1.0, 1_000_000)",
stmt="for x in it: x*x")
runner.timeit(
"int: x*...*x",
setup="from itertools import repeat; it = repeat(1, 1_000_000)",
stmt="for x in it: x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x")
runner.timeit(
"float: x*...*x",
setup="from itertools import repeat; it = repeat(1.0, 1_000_000)",
stmt="for x in it: x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x")Results from PGO on WSL:
Results from pgo using build.bat (MSVC):
|
Sorry, something went wrong.
|
@sweeneyde The speedups are worthwhile for less than 100 additional lines of code, IMO. The speedups on the micro benchmark shows that it works. Don't forget that |
Sorry, something went wrong.
|
Okay, that makes sense, thanks. Re-opened. |
Sorry, something went wrong.
|
🤖 New build scheduled with the buildbot fleet by @markshannon for commit 31c3bb9 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
Sorry, something went wrong.
|
Buildbot failures seem to be the usual suspects. |
Sorry, something went wrong.
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️Hi! The buildbot AMD64 FreeBSD Shared 3.x has failed when building commit 3b3d30e. What do you need to do:
You can take a look at the buildbot page here: https://buildbot.python.org/all/#builders/483/builds/974 Failed tests:
Failed subtests:
Summary of the results of the build (if available): == Tests result: FAILURE then FAILURE == 406 tests OK. 10 slowest tests:
1 test failed: 20 tests skipped: 2 re-run tests: Total duration: 31 min 6 sec Click to see traceback logsTraceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 813, in test_bt_full
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#1 <built-in method id of module object at remote 0x8014ac3b0>\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n#9 Frame 0x800235020, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 12, in <module> ()\n foo(1, 2, 3)\n' did not match '^.*\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \\(a=1, b=2, c=3\\)\n baz\\(a, b, c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \\(a=1, b=2, c=3\\)\n bar\\(a=a, b=b, c=c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \\(\\)\n foo\\(1, 2, 3\\)\n'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_concurrent_futures.py", line 1038, in test_idle_process_reuse_multiple
self.assertLessEqual(len(executor._processes), 2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 3 not less than or equal to 2
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 735, in test_pyup_command
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n#9 Frame 0x800235020, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 12, in <module> ()\n foo(1, 2, 3)\n' did not match '^.*\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 10, in baz \\(args=\\(1, 2, 3\\)\\)\n id\\(42\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \\(a=1, b=2, c=3\\)\n baz\\(a, b, c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \\(a=1, b=2, c=3\\)\n bar\\(a=a, b=b, c=c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \\(\\)\n foo\\(1, 2, 3\\)\n$'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 696, in test_basic_command
self.assertListing(' 5 \n'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 689, in assertListing
self.assertEndsWith(actual, expected)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 291, in assertEndsWith
self.assertTrue(actual.endswith(exp_end),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true : 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n 2 \n 3 def foo(a, b, c):\n 4 bar(a=a, b=b, c=c)\n 5 \n 6 def bar(a, b, c):\n >7 baz(a, b, c)\n 8 \n 9 def baz(*args):\n 10 id(42)\n 11 \n 12 foo(1, 2, 3)\n' did not end with ' 5 \n 6 def bar(a, b, c):\n 7 baz(a, b, c)\n 8 \n 9 def baz(*args):\n >10 id(42)\n 11 \n 12 foo(1, 2, 3)\n'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_concurrent_futures.py", line 1029, in test_idle_process_reuse_one
self.assertEqual(len(executor._processes), 1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 2 != 1
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 770, in test_up_then_down
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n#9 Frame 0x800235020, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 12, in <module> ()\n foo(1, 2, 3)\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n' did not match '^.*\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 10, in baz \\(args=\\(1, 2, 3\\)\\)\n id\\(42\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \\(a=1, b=2, c=3\\)\n baz\\(a, b, c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \\(a=1, b=2, c=3\\)\n bar\\(a=a, b=b, c=c\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \\(\\)\n foo\\(1, 2, 3\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 10, in baz \\(args=\\(1, 2, 3\\)\\)\n id\\(42\\)\n#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \\(a=1, b=2, c=3\\)\n baz\\(a, b, c\\)\n$'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 990, in test_print_after_up
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: "Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n#9 Frame 0x800235020, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 12, in <module> ()\n foo(1, 2, 3)\n'c' not found\n'b' not found\n'a' not found\n" did not match ".*\\nlocal 'c' = 3\\nlocal 'b' = 2\\nlocal 'a' = 1\\n.*"
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 1024, in test_locals_after_up
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n#9 Frame 0x800235020, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 12, in <module> ()\n foo(1, 2, 3)\nLocals for <module>\n' did not match '^.*\nLocals for foo\na = 1\nb = 2\nc = 3\nLocals for <module>\n.*$'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 793, in test_bt
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\nTraceback (most recent call first):\n <built-in method id of module object at remote 0x8014ac3b0>\n File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py", line 7, in bar\n baz(a, b, c)\n File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py", line 12, in <module>\n foo(1, 2, 3)\n' did not match '^.*\nTraceback \\(most recent call first\\):\n <built-in method id of module object .*>\n File ".*gdb_sample.py", line 10, in baz\n id\\(42\\)\n File ".*gdb_sample.py", line 7, in bar\n baz\\(a, b, c\\)\n File ".*gdb_sample.py", line 4, in foo\n bar\\(a=a, b=b, c=c\\)\n File ".*gdb_sample.py", line 12, in <module>\n foo\\(1, 2, 3\\)\n'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 981, in test_basic_command
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: "Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\n'args' not found\n" did not match ".*\\nlocal 'args' = \\(1, 2, 3\\)\\n.*"
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 711, in test_one_abs_arg
self.assertListing(' 9 def baz(*args):\n'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 689, in assertListing
self.assertEndsWith(actual, expected)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 291, in assertEndsWith
self.assertTrue(actual.endswith(exp_end),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true : 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n 9 def baz(*args):\n 10 id(42)\n 11 \n 12 foo(1, 2, 3)\n' did not end with ' 9 def baz(*args):\n >10 id(42)\n 11 \n 12 foo(1, 2, 3)\n'
Traceback (most recent call last):
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 1015, in test_basic_command
self.assertMultilineMatches(bt,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/test_gdb.py", line 297, in assertMultilineMatches
self.fail(msg='%r did not match %r' % (actual, pattern))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'Breakpoint 1 (builtin_id) pending.\n\nBreakpoint 1, builtin_id (self=<optimized out>, v=42) at Python/bltinmodule.c:1197\n1197\t PyObject *id = PyLong_FromVoidPtr(v);\n#4 Frame 0x800235110, for file /usr/home/buildbot/python/3.x.koobs-freebsd-564d/build/Lib/test/gdb_sample.py, line 7, in bar (a=1, b=2, c=3)\n baz(a, b, c)\nLocals for bar\na = 1\nb = 2\nc = 3\n' did not match '.*\\nargs = \\(1, 2, 3\\)\\n.*'
|
Sorry, something went wrong.
https://bugs.python.org/issue45367