<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-28369651345255756</id><updated>2011-07-07T21:55:53.231-07:00</updated><category term='floating point'/><category term='gil'/><category term='setcheckinterval'/><category term='python'/><category term='inf'/><category term='threading'/><title type='text'>Solving Problems With Python</title><subtitle type='html'>Seun Osewa's Python Programming Blog</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://seun-python.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28369651345255756/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://seun-python.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Seun Osewa</name><uri>http://www.blogger.com/profile/11257184260827538727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-28369651345255756.post-816179093250732713</id><published>2009-06-18T09:45:00.000-07:00</published><updated>2009-06-18T10:23:25.141-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inf'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='floating point'/><title type='text'>Smallest And Largest Floating Point Values In Python</title><content type='html'>In my production code, I have a function that calculates &lt;code class="prettyprint"&gt;a/(a+b)&lt;/code&gt;.  That function threw a &lt;code class="prettyprint"&gt;ZeroDivisionError&lt;/code&gt; at me this afternoon, so I decided to change the equation to &lt;code class="prettyprint"&gt;a/(a+b+sys.minfloat)&lt;/code&gt;, because I felt that was more elegant than writing a conditional function to check if &lt;code class="prettyprint"&gt;(a + b) == 0&lt;/code&gt;.  &lt;br /&gt;&lt;br /&gt;Turns out there is no 'minfloat' in the sys module, so I decided to write a function to calculate the smallest float myself.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&gt;&gt;&gt; def minfloat(guess):&lt;br /&gt; while(guess * 0.5 != 0):&lt;br /&gt;     guess = guess * 0.5&lt;br /&gt;        return guess&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; minfloat(+1.0)       # minimum positive value of a float&lt;br /&gt;4.9406564584124654e-324&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; minfloat(-1.0)      # minimum negative value of a float&lt;br /&gt;-4.9406564584124654e-324&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But I couldn't stop there.  Now I had to write a function to calculate the largest possible floating point value in Python, just for kicks:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&gt;&gt;&gt; def maxfloat(guess = 1.0):&lt;br /&gt;        while(guess * 2 != guess):&lt;br /&gt;            guess = guess * 2&lt;br /&gt;        return guess&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; maxfloat(+1.0)       # maximum positive value of a float&lt;br /&gt;inf&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; maxfloat(-1.0)      # maximum negative value of a float&lt;br /&gt;-inf&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is interesting.  Let's find out more about this "inf" value:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&gt;&gt;&gt; inf&lt;br /&gt;&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;  File "&lt;pyshell#26&gt;", line 1, in &lt;module&gt;&lt;br /&gt;    inf&lt;br /&gt;NameError: name 'inf' is not defined&lt;br /&gt;&gt;&gt;&gt; float("inf")&lt;br /&gt;inf&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; inf = maxfloat()&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; inf + inf&lt;br /&gt;inf&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; inf - inf&lt;br /&gt;nan&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; 1 / inf&lt;br /&gt;0.0&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; 1/(-inf)&lt;br /&gt;-0.0&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, check the relationship between minfloat and maxfloat:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&gt;&gt;&gt; 1 / minfloat(1.0)&lt;br /&gt;inf&lt;br /&gt;&gt;&gt;&gt; 1 / minfloat(-1.0)&lt;br /&gt;-inf&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28369651345255756-816179093250732713?l=seun-python.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://seun-python.blogspot.com/feeds/816179093250732713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://seun-python.blogspot.com/2009/06/floating-point-min-max.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28369651345255756/posts/default/816179093250732713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28369651345255756/posts/default/816179093250732713'/><link rel='alternate' type='text/html' href='http://seun-python.blogspot.com/2009/06/floating-point-min-max.html' title='Smallest And Largest Floating Point Values In Python'/><author><name>Seun Osewa</name><uri>http://www.blogger.com/profile/11257184260827538727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28369651345255756.post-6325476629060570074</id><published>2009-06-15T12:02:00.000-07:00</published><updated>2009-06-15T13:03:50.621-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='setcheckinterval'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gil'/><category scheme='http://www.blogger.com/atom/ns#' term='threading'/><title type='text'>Trivial Solution To CPU-Bound Thread Slowdown On Multicore Systems</title><content type='html'>According to &lt;a href="http://www.dabeaz.com/python/GIL.pdf"&gt;David Beasley&lt;/a&gt;, the CPython GIL doesn't just prevent CPU-bound applications from taking advantage of multiple cores.  He says it also slows them down on multicore systems.&lt;br /&gt;&lt;br /&gt;As an example, he says, following CPU-bound function runs is slower on multicore systems when run in two threads vs when run twice sequentially on the same thread:&lt;br /&gt;&lt;pre class="prettyprint"&gt;def counts(n=10000000):&lt;br /&gt;while n &gt; 0:&lt;br /&gt;  n -= 1&lt;/pre&gt;&lt;br /&gt;I tested the claim by running this little program (let's call it &lt;strong&gt;gil.py&lt;/strong&gt;)&lt;br /&gt;&lt;pre class="prettyprint"&gt;from time import time&lt;br /&gt;from threading import Thread&lt;br /&gt;&lt;br /&gt;def counts(n=10000000):&lt;br /&gt;while n &gt; 0:&lt;br /&gt;   n -= 1&lt;br /&gt;&lt;br /&gt;def measure(f, comment):&lt;br /&gt;t=time()&lt;br /&gt;f()&lt;br /&gt;print time()-t, "seconds"&lt;br /&gt;&lt;br /&gt;def sequ():&lt;br /&gt;counts()&lt;br /&gt;counts()&lt;br /&gt;&lt;br /&gt;def para():&lt;br /&gt;t1 = Thread(target=counts,args=())&lt;br /&gt;t1.start()&lt;br /&gt;t2 = Thread(target=counts,args=())&lt;br /&gt;t2.start()&lt;br /&gt;t1.join(); t2.join()&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;measure(sequ, "Sequential Execution")&lt;br /&gt;measure(para, "Sequential Execution")&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the result from running the script on a Core Duo 2 laptop:&lt;br /&gt;&lt;pre class="prettyprint"&gt;C:\Py&gt;python gil.py&lt;br /&gt;Sequential Execution: 4.81399989128 seconds&lt;br /&gt;Parallel Execution: 11.2730000019 seconds&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;He's sort-of right in this case.  So why has the GIL has survived?  Partly because the problem is easily solved.&lt;br /&gt;&lt;br /&gt;One way to do that is to use the sys.checkinterval function which allows CPU-bound threads to do a little more work before giving up control of the GIL.  Since the overhead of GIL passing in the above is more than 100%, we need to increase the check interval by a factor of hundred or so. (The default is 100.)&lt;br /&gt;&lt;br /&gt;Just add the following to gil.py after "if __name__ == '__main__'":&lt;br /&gt;&lt;pre class="prettyprint"&gt;import sys&lt;br /&gt;sys.setcheckinterval(100*100)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's run it again and see what happens:&lt;br /&gt;&lt;pre class="prettyprint"&gt;C:\Py&gt;python gil.py&lt;br /&gt;Sequential Execution: 4.63999986649 seconds&lt;br /&gt;Parallel Execution: 4.63199996948 seconds&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Problem solved&lt;/strong&gt;!&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Avoiding Pre-emption Altogether&lt;/h4&gt;Personally, I like to include "&lt;code class="prettyprint"&gt;sys.setcheckinterval(sys.maxint)&lt;/code&gt;" in all my scripts, so I don't have to lock shared data structures when manipulating them in Python code.  If you do that, your threads will never be pre-empted as long as you don't call any blocking functions that release the GIL, and you can avoid the overhead of fine-grained locking, potential deadlocks, etc. What do you think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28369651345255756-6325476629060570074?l=seun-python.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://seun-python.blogspot.com/feeds/6325476629060570074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://seun-python.blogspot.com/2009/06/gil.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28369651345255756/posts/default/6325476629060570074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28369651345255756/posts/default/6325476629060570074'/><link rel='alternate' type='text/html' href='http://seun-python.blogspot.com/2009/06/gil.html' title='Trivial Solution To CPU-Bound Thread Slowdown On Multicore Systems'/><author><name>Seun Osewa</name><uri>http://www.blogger.com/profile/11257184260827538727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry></feed>
