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

AtomicInt #7

Merged
merged 17 commits into from
Dec 17, 2023
Merged

AtomicInt #7

merged 17 commits into from
Dec 17, 2023

Conversation

dpdani
Copy link
Owner

@dpdani dpdani commented Dec 15, 2023

No description provided.

@dpdani
Copy link
Owner Author

dpdani commented Dec 16, 2023

comparing the following programs, AtomicInt provides an easy way to achieve correctness, with the nice feature of being lock-free.
using AtomicInt.get_handle() provides great performance improvements.

also see colesbury/nogil#121

$ python
Python 3.9.10 (main, Nov  8 2023, 12:16:13)
[nogil, GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

import threading


class Spam:
    def __init__(self):
        self.counter = 0


spam = Spam()
print(f"{spam.counter=}")


def incr():
    global spam
    for _ in range(5_000_000):
        spam.counter += 1


threads = [threading.Thread(target=incr) for _ in range(3)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(f"{spam.counter=}")
$ /bin/time -p python ./atomic_int_0.py
spam.counter=0
spam.counter=5079663
real 62.42
user 34.62
sys 31.22
$ PYTHONGIL=1 /bin/time -p python ./atomic_int_0.py
spam.counter=0
spam.counter=15000000
real 1.22
user 1.21
sys 0.01

import threading

import cereggii


class Spam:
    def __init__(self):
        self.counter = cereggii.AtomicInt(0)


spam = Spam()
print(f"{spam.counter.get()=}")


def incr():
    global spam
    for _ in range(5_000_000):
        spam.counter += 1


threads = [threading.Thread(target=incr) for _ in range(3)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(f"{spam.counter.get()=}")
$ /bin/time -p python ./atomic_int_1.py
spam.counter.get()=0
spam.counter.get()=15000000
real 56.53
user 26.61
sys 31.90

import threading

import cereggii


class Spam:
    def __init__(self):
        self.counter = cereggii.AtomicInt(0)


spam = Spam()
print(f"{spam.counter.get()=}")


def incr():
    global spam
    h = spam.counter.get_handle()
    for _ in range(5_000_000):
        h += 1


threads = [threading.Thread(target=incr) for _ in range(3)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(f"{spam.counter.get()=}")
$ /bin/time -p python ./atomic_int_2.py
spam.counter.get()=0
spam.counter.get()=15000000
real 2.23
user 6.55
sys 0.00

@dpdani dpdani merged commit 9832ca7 into dev Dec 17, 2023
2 checks passed
@dpdani dpdani deleted the feature/atomic-int branch December 17, 2023 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant