GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||
GeezerVison is showing github.com — gh-120496: Use CAS approach for rangeiter_next by corona10 · Pull Request #120534 · python/cpython Conversation
|
|
Thanks for doing this! Do you have any benchmark results on how much the perf impact is? versus say using |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I will try to prepare :) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I am not sure this will be a fair benchmark, but it shows different strengths in terms of technique and size of N. Single threadimport pyperf runner = pyperf.Runner() runner.timeit(name="bench iter single", stmt=""" data = list(it) """, setup = """ N = 100 it = iter(range(N)) """ )
Mutl threadimport pyperf runner = pyperf.Runner() runner.timeit(name="bench iter multi", stmt=""" for _ in range(100): it = iter(range(N)) with concurrent.futures.ThreadPoolExecutor() as executor: data = list(executor.map(lambda _: next(it), range(N))) """, setup = """ import concurrent.futures N = 100 """ )
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Hmmm the perf difference is not that large. That might imply that we should just use critical section for simplicity, and hope that someone on PyPI publishes a "prange()" or something like that. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Yeah, I prefer this one. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if (len <= 0) { | ||
| return NULL; | ||
| } | ||
| long result = _Py_atomic_load_long_relaxed(&r->start); |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
What if we have a range object with len=1 and many threads simultaneously at this point? The check on len has already been done, so the threads each increment the value of start and we end up with a value for result larger than end.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Maybe fail at _Py_atomic_compare_exchange_long?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ah.. yes understood what you pointed out.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
There will be a slight timing issue. Then yes, let's just use the critical section that @Fidget-Spinner also preferred.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
To prepare for the overcommitted issue, we can validate the value of the result by comparing the end value.
But let's just use critical section approach.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
See: #120540 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.