<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>cat /dev/brain/rand &gt; /srv/tumblr</title><generator>Tumblr (3.0; @jbedo)</generator><link>http://blog.cua0.org/</link><item><title>My new AWUS036H long-range USB WIFI adapter with 5dB antenna has...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m1tkwoLzQn1qh9kzco1_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://25.media.tumblr.com/tumblr_m1tkwoLzQn1qh9kzco2_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;p&gt;My new AWUS036H long-range USB WIFI adapter with 5dB antenna has arrived!  Initial tests under linux shows 60 wifi stations from my desk.  Now to try getting it running under plan 9.&lt;/p&gt;</description><link>http://blog.cua0.org/post/20309185123</link><guid>http://blog.cua0.org/post/20309185123</guid><pubDate>Sun, 01 Apr 2012 23:26:00 +0200</pubDate></item><item><title>Uploading and deleting from flickr</title><description>&lt;p&gt;I&amp;#8217;ve now implemented uploading and deletion of pics.  It&amp;#8217;s now pretty
complete:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;horizon% cp /tmp/glenda.jpg /n/flickr
horizon% page /n/flickr/glenda.jpg
reading through graphics...
horizon% rm /n/flickr/glenda.jpg
horizon% ls /n/flickr/glenda.jpg
ls: /n/flickr/glenda.jpg: '/n/flickr/glenda.jpg' file not found
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Current limitations:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Upload expects jpg&lt;/li&gt;
&lt;li&gt;Does not detect presence of original files; currently reads large sized
jpegs from flickr&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These are pretty minor but I&amp;#8217;ll fix them eventually.  For now, I can
easily copy stuff to flickr, and copy down all my old pics (in large
jpeg format) to my playbook.&lt;/p&gt;</description><link>http://blog.cua0.org/post/20227195299</link><guid>http://blog.cua0.org/post/20227195299</guid><pubDate>Sat, 31 Mar 2012 17:22:17 +0200</pubDate></item><item><title>Read and rename implemented for flickrfs</title><description>&lt;p&gt;I have implemented reading and renaming in my flickrfs server.
Example session:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;horizon% 8.flickrfs
horizon% cd /n/flickr
horizon% page scan0001.jpg
reading through graphics...
horizon% mv scan0001.jpg 2cv.jpg
horizon% ls 2*
2cv.jpg
horizon% 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This sets the title of the image (previously scan0001) to 2cv.  This
is verifiable via the &lt;a href="http://www.flickr.com/photos/29941991@N06/5848913554/"&gt;web interface&lt;/a&gt;.  UTF-8 works fine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;horizon% mv scan0006.jpg 'Sacré Cœur.jpg'
horizon% 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;with the result &lt;a href="http://www.flickr.com/photos/29941991@N06/6133106069/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.cua0.org/post/20189047209</link><guid>http://blog.cua0.org/post/20189047209</guid><pubDate>Sat, 31 Mar 2012 00:02:09 +0200</pubDate></item><item><title>Towards a 9p flickr server</title><description>&lt;p&gt;One of the web services I use reasonably frequently is
&lt;a href="http://www.flickr.com/photos/29941991@N06/"&gt;flickr&lt;/a&gt; where I like to show my amature photos.  Up until now
I&amp;#8217;ve just been using the web interface to upload my images.  It is
however really slow and I hate all the clicking, so I thought a 9p
fileserver for flickr would be useful for me.  Also, I&amp;#8217;d like to be
able to sync my playbook with flickr and having both mounted would
make this much easier (rsync for example).&lt;/p&gt;

&lt;p&gt;So I started writing one and I finally got a basic skeleton together.
The auth dance took me a while to work out (I&amp;#8217;m not experienced with
web apps) but I finally got there.  The fileserver is written for plan
9 and I use &lt;a href="http://man.cat-v.org/plan_9/4/webfs"&gt;webfs(4)&lt;/a&gt; to communicate with flickr and
&lt;a href="http://man.cat-v.org/plan_9/4/factotum"&gt;factotum(4)&lt;/a&gt; to store authentication tokens.&lt;/p&gt;

&lt;p&gt;At the moment all my file server does is list my photos.  Here&amp;#8217;s an
example session:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;horizon% 8.flickrfs
horizon% ls /n/flickr
'/n/flickr/Assiette de crudités'
'/n/flickr/Assiette de pêcher'
'/n/flickr/Coffee corner'
'/n/flickr/Confit de Canard'
'/n/flickr/Cuisse de poulet au vin riz avec poireaux'
/n/flickr/Escargots
/n/flickr/Hors-d’œuvre
/n/flickr/IMAG0097
/n/flickr/IMAG0101
/n/flickr/IMG_20090627_0463
/n/flickr/IMG_20090630_0666
...
/n/flickr/small_L9992400_bw
/n/flickr/small_L9992401_bw
/n/flickr/small_L9992403_bw
/n/flickr/small_L9992404_bw
/n/flickr/small_L9992405_bw
/n/flickr/small_L9992411_bw
/n/flickr/small_L9992413_bw
/n/flickr/small_L9992416
/n/flickr/small_L9992420_bw
horizon% ls /n/flickr |wc -l
    228
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next up I&amp;#8217;ll probably implement renaming so I can give them some
better names, they&amp;#8217;re admittedly utilitarian.  I won&amp;#8217;t share the source
just yet as it&amp;#8217;s extremely underdeveloped.  This is my first time
writing both a 9p server and a web app, so I&amp;#8217;m learning a lot.&lt;/p&gt;</description><link>http://blog.cua0.org/post/20128707055</link><guid>http://blog.cua0.org/post/20128707055</guid><pubDate>Thu, 29 Mar 2012 22:06:00 +0200</pubDate></item><item><title>When's my next train?</title><description>&lt;p&gt;After living on local solar time for a couple of days I can say that
it&amp;#8217;s much better than the ridiculous daylight saving time.  As the sun
rises at the proper time (around 6am) it is much easier to wake up and
get going.  Another (side) benefit is that public transport is less
crowded as peak hour is naturally avoided.&lt;/p&gt;

&lt;p&gt;However, catching trains is more difficult as it requires much more
mental arithmetic.  I therefore decided that what I need is a little
program to just tell me when the next train comes in minutes and then
I can easily work out when I should leave.  Sounds simple, and you&amp;#8217;d
think this would already exist, but the SNCF/Transilien website gives
absolute times for the next train not relative.  I also feel using a
web browser is too cumbersome.  I thus wrote a little shell script to
tell me when the next trains to/from Paris/Évry come.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s some examples, first the direction Paris to Évry-Courcouronnes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    term% rer-d
    BIPE:   3m
    BIPE:   18m
    term% 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and from Évry-Courcouronnes to Paris:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    term% rer-d -t
    MIPE:   4m
    MIPE:   18m
    MIPE:   34m
    MIPE:   48m
    MIPE:   63m
    MIPE:   78m
    term% 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The shell script is effectively a simple awk script that scrapes the
transilien wap website for the information.  Luckily for me, the
website also contains the current time to calculate the deltas (awk
has no time functions).  Here&amp;#8217;s the script in all it&amp;#8217;s simplicity:&lt;/p&gt;

&lt;script src="https://gist.github.com/2218677.js?file=rer-d"&gt;&lt;/script&gt;&lt;h2&gt;Bugs&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;I hardcoded Évry–Courcouronnes as it&amp;#8217;s the only place I take trains to&lt;/li&gt;
&lt;li&gt;As it scrapes a webpage it&amp;#8217;s subject to change&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.cua0.org/post/20016155009</link><guid>http://blog.cua0.org/post/20016155009</guid><pubDate>Tue, 27 Mar 2012 20:25:00 +0200</pubDate></item><item><title>What time is it?</title><description>&lt;p&gt;Today we shifted to daylight saving time and I lost 1 hour of sleep.
I didn&amp;#8217;t notice for a while as most of my clocks correct
automatically, and when I finally noticed I was disappointed.  I don&amp;#8217;t
like daylight saving time as I feel it&amp;#8217;s disruptive and does not lead
to the purported energy saving benefit.  Furthermore, I already think
Paris is offset too far from &lt;a href="https://en.wikipedia.org/wiki/Local_mean_time"&gt;local mean time&lt;/a&gt;, given that we
have a longitude of only 2°2′ yet we are in the UTC-1 timezone.&lt;/p&gt;

&lt;p&gt;I rapidly came to the conclusion that what I really wanted was to live
on &lt;a href="https://en.wikipedia.org/wiki/Solar_time#Apparent_solar_time"&gt;local solar time&lt;/a&gt; and not some artificial construction.  To
this end I wrote a small program to calculate the current local solar
time given a longitudinal position, the date and Greenwich mean time.
Of course the latter two are pulled automatically from the system
clock, so it needs to be in sync with Greenwich (easy enough with
&lt;a href="http://man.cat-v.org/plan_9/8/TIMESYNC"&gt;timesync(8)&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The program works by first calculating local mean time and then
correcting this using the &lt;a href="https://en.wikipedia.org/wiki/Equation_of_time"&gt;equation of time&lt;/a&gt; to local solar time.
Local mean time is easy to calculate as it works out to just a 4
minute difference for each degree (longitude).  Calculating the
equation of time is more tricky, but there are many available
approximations.  I chose to use the approximation given in wikipedia,
but another is implemented (Woolf 1968) but commented out.  Basically,
the equation of time corrects for two major components: the
eccentricity of the Earth&amp;#8217;s orbit and the obliquity of the ecliptic.&lt;/p&gt;

&lt;p&gt;My code works on both Plan 9 and Plan 9 Port.  I now have the Plan 9
Port version loaded into my &lt;a href="http://wmii.suckless.org/"&gt;wmii&lt;/a&gt; status bar for local solar
time in Paris and Melbourne.  As of this writing, the local solar time
in Paris is 20:08 while the UTC+2 (dst) is 22:05.&lt;/p&gt;

&lt;p&gt;Just for fun I added a flag (-x) to print the local solar time in
hexadecimal instead.  In this case, it prints out the local solar time
rescaled and formatted to the &lt;a href="http://www.intuitor.com/hex/hexclock.html"&gt;hexclock&lt;/a&gt; style.  The current
local solar time as of this writing in hex is D_81_8.&lt;/p&gt;

&lt;script src="https://gist.github.com/2199439.js?file=solar.c"&gt;&lt;/script&gt;&lt;h2&gt;Bugs&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Default latitude is hard coded.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Woolf, H. M. (1968), &amp;#8220;On the Computation of Solar Evaluation Angles and the Determination of Sunrise and Sunset Times,&amp;#8221; National Aeronautics and Space Administration Report NASA TM-X -164, September&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.cua0.org/post/19911048258</link><guid>http://blog.cua0.org/post/19911048258</guid><pubDate>Sun, 25 Mar 2012 22:13:00 +0200</pubDate></item><item><title>Postscript quines</title><description>&lt;p&gt;I&amp;#8217;ve just learnt &lt;a href="http://en.wikipedia.org/wiki/PostScript"&gt;postscript&lt;/a&gt; and thought I&amp;#8217;d amuse mysef by trying to write some &lt;a href="http://en.wikipedia.org/wiki/Quine_(computing)"&gt;quines&lt;/a&gt;.  Here&amp;#8217;s one console quine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{(pstack exec) =}
pstack exec
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and one using the graphical device:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;&amp;lt; /PageSize [5000 20] /Orientation 0 &amp;gt;&amp;gt; setpagedevice /Courier
findfont 18 scalefont setfont 0 4 moveto /l {( ) dup 0 40 put
show} def /r {( ) dup 0 41 put show} def /quine {dup show l
show r ( quine showpage) show} def (&amp;lt;&amp;lt; /PageSize [5000 20]
/Orientation 0 &amp;gt;&amp;gt; setpagedevice /Courier findfont 18 scalefont
setfont 0 4 moveto /l {( ) dup 0 40 put show} def /r {( ) dup
0 41 put show} def /quine {dup show l show r ( quine showpage)
show} def ) quine showpage
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The latter is by far the ugliest quine I&amp;#8217;ve ever seen, but at least the former is elegent.&lt;/p&gt;</description><link>http://blog.cua0.org/post/18657327811</link><guid>http://blog.cua0.org/post/18657327811</guid><pubDate>Sat, 03 Mar 2012 12:23:43 +0100</pubDate></item><item><title>Cache oblivious matrix multiplication with Hilbert space-filling curves</title><description>&lt;p&gt;A well known problem in computer science is how to do matrix multiplication.  Usually, matrices are stored in memory in either row-major or column-major format, i.e., matrices are stored sequentially in either row order or column order.  The conventions vary a little, for example Fortran uses column-major and C uses row-major, but the differences between the two are mostly notational and they both share the same disadvantage: either column or row spatial locality is minimised in one dimension but not both.&lt;/p&gt;

&lt;p&gt;This has no impact if the only matrix operations used access the elements in one order only, in fact it&amp;#8217;s optimal, but it is a problem for operations that stride across both dimensions simultaneously such as matrix multiplication done in the naïve way to calculate C = AB:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for i in 1:rows(A)
    for j in 1:cols(B)
        for k in 1:cols(A)
            C[i, j] += A[i, k] * B[k, j]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For small matrices this works fine; the three matrices fit into the processor cache so the pipeline can be kept full.  The problem is for sufficiently large matrices, each iteration causes a cache miss which slows things down considerably.&lt;/p&gt;

&lt;p&gt;The traditional method for addressing this problem is blocking.  Instead of calculating the matrix C naïvely as above by iterating through entire rows and columns, you calculate it in blocks.  This is the approach taken by BLAS.  Unfortunately, the optimal block sizes are very processor dependent as the cache architecture varies quite considerably between processors, so it must be tuned very carefully for each machine to achieve the best performance.&lt;/p&gt;

&lt;p&gt;A more radical and interesting idea is to change the storage order of the matrix elements.  That is, instead of optimising in one dimension only, the elements are stored to preserve spatial locality in both dimensions.  This is done by storing elements along a space filling curve.  Indeed, if a fractal space filling curve is chosen then matrix multiplication becomes &lt;a href="https://en.wikipedia.org/wiki/Cache_oblivious"&gt;cache oblivious&lt;/a&gt;, that is it uses the cache well at all levels.&lt;/p&gt;

&lt;p&gt;In particular, the &lt;a href="https://en.wikipedia.org/wiki/Hilbert_curve"&gt;Hilbert fractal space filling curve&lt;/a&gt; has been proposed recently as a matrix storage order, in particular as a sparse matrix storage order (Hasse et al. 2007).  I therefore thought I&amp;#8217;d have a quick play with it and hacked up the following primitive benchmark.&lt;/p&gt;

&lt;script src="https://gist.github.com/1407483.js?file=hilbert.c"&gt;&lt;/script&gt;&lt;p&gt;The implementation stores matrices in a dense array indexed using the Hilbert curve.  Upon matrix creation, I calculate two arrays for iterating through a matrix by rows or columns (these are the Δi and Δj arrays in the matrix structure).  These arrays contain an offset to the next element, so iterating through the elements is as simple as adding the offset to the current pointer.  The functions for converting ordinary indices to Hilbert index were copied from the &lt;a href="https://en.wikipedia.org/wiki/Hilbert_curve"&gt;Wikipedia article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Benchmarking was done by counting elapsed CPU cycles with increasing matrix size.  All benchmarking was done on an Intel Atom machine running the Plan 9 operating system.  I timed matrix creation (for the Hilbert storage order) as the time it takes to calculate the offset arrays is important.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lvg8vfI35R1qg9u7s.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the results.  The x-axis is the matrix size and the y-axis the clock cycles.  The red plot shows the cycles required to create the Hilbert matrix array (and delta arrays), the blue shows the naïve matrix product, in green is the cycles for Hilbert ordering, and finally in purple is the combined init + matrix product for Hilbert ordering.  Clearly the Hilbert ordering is much better than the naïve method, though the scale chosen makes it look particularly bad.  Here is is with a log axis:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lvg8u61M5c1qg9u7s.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;As expected, the naïve method is faster for small matrices that fit nicely in the cache, but the Hilbert ordering is much better for larger matrices where it doesn&amp;#8217;t.  All in all it&amp;#8217;s a pretty nice speed up (4.7×) for pretty minimal coding effort and zero tuning.  Bear in mind also that my code is just hacked together with no optimisation.&lt;/p&gt;

&lt;p&gt;So I quite like it, it was easy and has appreciable benefit.  However, the conversion between indexing systems is a bit heavy.  In some ways, &lt;a href="https://en.wikipedia.org/wiki/Z-order_%28curve%29"&gt;Morton ordering&lt;/a&gt; is more appealing because the translation is much faster, requiring only bit interleaving by simple bit operations (Wise et al. 2001) replacing the delta arrays I used to traverse by row/col.  Also, addressing a Morton ordered matrix as a &lt;a href="https://en.wikipedia.org/wiki/Quad_tree"&gt;quadtree&lt;/a&gt; is actually quite easy (Wise 2000) so implementing smarter matrix multiplication algorithms such as &lt;a href="https://en.wikipedia.org/wiki/Strassen%27s_algorithm"&gt;Strassen&amp;#8217;s algorithm&lt;/a&gt; is simpler.&lt;/p&gt;

&lt;p&gt;There is also an interesting article (Bader 2006) that uses a Pino curve instead of either Morton or Hilbert.  They propose an algorithm that does matrix multiplication without any jumps at all.  I haven&amp;#8217;t had the time to read the article in more detail.&lt;/p&gt;

&lt;h2&gt;Bugs&lt;/h2&gt;

&lt;p&gt;The dense storage is wasteful.  For square matrices of power 2 it is optimal, for anything otherwise it wastes space.  A lot of space if it&amp;#8217;s a thin matrix.&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Wise et al. 2001: &lt;a href="http://dx.doi.org/10.1145%2F379539.379559"&gt;Language support for Morton-order matrices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wise 2000: &lt;a href="http://dx.doi.org/10.1007%2F3-540-44520-X_108"&gt;Ahnentafel Indexing into Morton-Ordered Arrays, or Matrix Locality for Free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Haase et al. 2007: &lt;a href="http://dx.doi.org/10.1080%2F17445760601122084"&gt;A Hilbert-order multiplication scheme for unstructured sparse matrices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Bader and Zenger 2006: &lt;a href="http://dx.doi.org/10.1016%2Fj.laa.2006.03.018"&gt;Cache oblivious matrix multiplication using an element ordering based on a Peano curve&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.cua0.org/post/13523899371</link><guid>http://blog.cua0.org/post/13523899371</guid><pubDate>Wed, 30 Nov 2011 02:16:42 +0100</pubDate></item><item><title>Installing cyanogenmod on HTC Desire</title><description>&lt;p&gt;To install inferno on android you need a rooted phone.  Since the inferno guys use &lt;a href="http://www.cyanogenmod.com/"&gt;cyanogenmod&lt;/a&gt; I thought I&amp;#8217;d load that up and go from there.  In any case, I was running Frozen Yoghurt and not Ginger Bread so my phone was out on date anyway.&lt;/p&gt;

&lt;p&gt;I found some &lt;a href="http://wiki.cyanogenmod.com/wiki/HTC_Desire_%28GSM%29:_Full_Update_Guide"&gt;overly complicated instructions&lt;/a&gt; on the cyanogenmod wiki that provided a starting point.  The process is much simpler if you load up the zip files and then run Revolutionary to install and launch ClockworkMod.  Of course all this voids the warranty.  Here&amp;#8217;s what I did:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Downloaded the &lt;a href="http://download.cyanogenmod.com/?type=stable&amp;amp;device=bravo"&gt;cyanogenmod image&lt;/a&gt; and the &lt;a href="http://wiki.cyanogenmod.com/wiki/Latest_Version#Google_Apps"&gt;Google apps&lt;/a&gt; and place them at the root of the SD card.&lt;/li&gt;
&lt;li&gt;Ran &lt;a href="http://revolutionary.io/"&gt;Revolutionary&lt;/a&gt; to set S-OFF and install ClockworkMod.  No need to note down your serial number first, Revolutionary tells it to you.&lt;/li&gt;
&lt;li&gt;Revolutionary left the phone in the bootloader, so I launched ClockworkMod recovery directly.&lt;/li&gt;
&lt;li&gt;Wiped the data and installed both zip files from the sd card&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;That was it, my phone is now running Cyanogenmod.  First impressions are pretty good, it feels snappier despite all the useless animations (which can be disabled).  There&amp;#8217;s also a nice &lt;a href="http://www.cyanogenmod.com/about"&gt;guide&lt;/a&gt; outlining all the features.&lt;/p&gt;</description><link>http://blog.cua0.org/post/10450883078</link><guid>http://blog.cua0.org/post/10450883078</guid><pubDate>Tue, 20 Sep 2011 22:02:00 +0200</pubDate></item><item><title>Inferno for android</title><description>&lt;p&gt;It&amp;#8217;s been a while since my last blog post, time to get back into it with something small.  Over the weekend there was a lot of traffic on the &lt;a href="http://9fans.net/archive/"&gt;9fans mailing list&lt;/a&gt; about &lt;a href="http://9fans.net/archive/2011/09/308"&gt;a port&lt;/a&gt; of &lt;a href="http://inferno-os.org/"&gt;Inferno&lt;/a&gt; to android.  The port replaces the whole Java machinery instead of running on top of it.  The &lt;a href="http://www.youtube.com/watch?v=dF_-jQc53jw"&gt;video demonstration&lt;/a&gt; looks quite snappy, I&amp;#8217;m tempted to install it on my HTC desire and have a play.&lt;/p&gt;</description><link>http://blog.cua0.org/post/10399235973</link><guid>http://blog.cua0.org/post/10399235973</guid><pubDate>Mon, 19 Sep 2011 12:25:39 +0200</pubDate></item><item><title>Controlling GPU temperatures</title><description>&lt;p&gt;I&amp;#8217;ve recently taken possession of two &lt;a href="http://www.msi.com/product/vga/R6990-4PD4GD5.html"&gt;ATI 6990&lt;/a&gt; graphics cards for the purposes of GPU computation.  A few days ago, Paris had a &amp;#8220;heat wave&amp;#8221; where the temperature reached around 37°.  As my apartment does not have any airconditioning, I was worried for the life of my GPUs, especially as they&amp;#8217;re overclocked.&lt;/p&gt;

&lt;p&gt;My solution was to run the fans at 100% and to hack up a quick program to monitor the core temperatures and adjust the clock speeds down accordingly.  This is done using proportional feedback control.  As changing the clock speeds flushes the pipeline, I introduced hysteresis around the target temperature.  Furthermore, current loads are also monitored, and clock speeds are only incremented if the load is above a threshold.  This is to prevent turning up the clock speeds while idle and then burning the GPUs as soon as they&amp;#8217;re loaded.  The clock speed range is also limited.&lt;/p&gt;

&lt;p&gt;It seems to work ok, but the code is quite hacky and I haven&amp;#8217;t tested it with any other cards.  Moreover, the P constant for the controller was not really tuned that carefully.  Use at own risk.  Amazingly, it&amp;#8217;s written for linux not plan 9.&lt;/p&gt;

&lt;script src="https://gist.github.com/1058282.js?file=tempmon.c"&gt;&lt;/script&gt;</description><link>http://blog.cua0.org/post/7116257378</link><guid>http://blog.cua0.org/post/7116257378</guid><pubDate>Fri, 01 Jul 2011 12:45:00 +0200</pubDate><category>ati</category><category>gpu</category><category>temperature</category><category>control</category></item><item><title>S3Venti port</title><description>&lt;p&gt;In an &lt;a href="http://blog.cua0.org/post/3341421113/hosting-venti-arenas-on-amazon-s3"&gt;earlier post&lt;/a&gt; I discussed using &lt;a href="https://s3.amazonaws.com/"&gt;Amazon S3&lt;/a&gt; as a venti block server for backup using the &lt;a href="http://9fans.net/archive/2008/02/343"&gt;s3venti&lt;/a&gt; code of Richard Bilson.  This code was written for &lt;a href="http://swtch.com/plan9port/"&gt;plan 9 port&lt;/a&gt; and not for a native &lt;a href="http://plan9.bell-labs.com/plan9/"&gt;plan 9&lt;/a&gt; installation.  Now that I use plan 9 almost exclusively, I wanted to run the s3venti server from plan 9.  Thus I ported it:&lt;/p&gt;

&lt;script src="https://gist.github.com/888244.js?file=gistfile1.diff"&gt;&lt;/script&gt;&lt;p&gt;The patch is for Richard&amp;#8217;s code found on sources in contrib/rcbilson/s3venti.  I&amp;#8217;ve tested it lightly with the &lt;a href="http://man.cat-v.org/plan_9/1/vac"&gt;vac&lt;/a&gt; tools and also &lt;a href="http://man.cat-v.org/plan_9/1/venti"&gt;venti/copy&lt;/a&gt; and it seems to work fine.&lt;/p&gt;</description><link>http://blog.cua0.org/post/4106142193</link><guid>http://blog.cua0.org/post/4106142193</guid><pubDate>Sat, 26 Mar 2011 13:49:21 +0100</pubDate><category>plan 9</category><category>venti</category><category>s3</category></item><item><title>Adjusting image contrast</title><description>&lt;p&gt;I wanted to do some simple image manipulations under Plan 9 for my photographs.  I don&amp;#8217;t like to edit my images much and prefer to keep them close to what the camera produces.  Thus, I don&amp;#8217;t really need many operations, only resizing and image contrast enhancement.  The former is already available in Plan 9 with the resample program, but I couldn&amp;#8217;t find anything to do the latter.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a program to do image contrast enhancement through histogram stretching:&lt;/p&gt;

&lt;script src="https://gist.github.com/878239.js?file=relevel.c"&gt;&lt;/script&gt;&lt;p&gt;This is pretty similar to the autolevels command available in photoshop/gimp, with a default of 1% clipping on the shadows and 0.5% on the highlights.  Input/output is via stdin/stdout, and the program reads/writes Plan 9 image format so it forms part of a pipeline.  Here&amp;#8217;s an example invocation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    jpg -t9 input.jpg | resample -x 1000 | relevel -h 0.01 | topng &amp;gt; output.png
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or with djpeg/cjpeg:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    djpeg -scale 1/4 input.jpg | ppm -t9 | relevel | toppm | cjpeg &amp;gt; output.jpg
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.cua0.org/post/3978112846</link><guid>http://blog.cua0.org/post/3978112846</guid><pubDate>Sun, 20 Mar 2011 10:44:00 +0100</pubDate></item><item><title>Plan 9 CPU server on a floppy</title><description>&lt;p&gt;One of the nice things about Plan 9 is that it has separate cpu, auth, and file servers.  This means it&amp;#8217;s possible to have a diskless CPU server for running numerical stuff that connects to a remote auth and file server.  This quite a useful case for me, as I can for example quickly setup any machine as a CPU server and use it to run my numerical code off my file server.  I&amp;#8217;m going to outline the steps needed here to create a boot floppy (yes floppy) for launching a CPU server.  In particular, I&amp;#8217;ve been looking at doing this using virtualisation via QEMU.&lt;/p&gt;

&lt;p&gt;The first step is to create a kernel that is small enough to fit on a floppy.  This can be accomplished by removing fossil and venti from the kernel &amp;#8212; as we&amp;#8217;re creating a pure CPU server there&amp;#8217;s no need for these file systems anyway.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    cd /sys/src/9/pc
    cat pccpuf | sed 's,^.*fossil/fossil.*,#&amp;amp;,' | sed 's,^.*venti/venti.*,#&amp;amp;,' &amp;gt;pccpufu
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;m using KVM on multicore machines, so I want to have SMP capabilities.  Unfortunately, I had some trouble with the APIC code in the Plan 9 kernel with KVM virtualised processors. To get it to boot with multiple processors I had to disable the LAPIC frequency check (not a good solution) in /sys/src/9/pc/apic.c:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    344c344
    &amp;lt;           if(lapictimer.hz &amp;gt; hz+(hz/10))
    ---
    &amp;gt;           /*if(lapictimer.hz &amp;gt; hz+(hz/10))
    346c346
    &amp;lt;                   lapictimer.hz, hz);
    ---
    &amp;gt;                   lapictimer.hz, hz);*/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the kernel can be compiled:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    mk 'CONF=pccpufu'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next step is to create a plan9.ini boot file specifying which kernel to load and what fileserver and authservers to use.  This is fairly straight forward:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    ramfs
    cat &amp;gt; /tmp/plan9.ini &amp;lt;&amp;lt; EOF
    nvr=fd!0!plan9.nvr
    bootfile=fd0!dos!9pccpufu.gz
    bootargs=tcp
    nobootprompt=tcp
    mouseport=ps2
    sysname=rubis
    fs=192.168.0.2
    auth=192.168.0.2
    EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The last three lines should be changed depending on your network configuration.  If fs and auth are not specified it will be prompted for during boot.  Now the boot floppy can be created, mounted, and the kernel copied across:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pc/bootfloppy /tmp/cpusrv.img /tmp/plan9.ini
    dossrv
    mount -c /srv/dos /n/a: /tmp/cpusrv.img
    gzip &amp;lt; /sys/src/9/pc/9pccpufu &amp;gt; /n/a:/9pccpufu.gz
    unmount /n/a:
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s it, /tmp/cpusrv.img should be a boot floppy.  Launching it using KVM should be as simple as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    qemu -no-kvm-irqchip -fda cpusrv.img -net nic -net user -redir tcp:17010::17010
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of couse you may wish to use more than one cpu (-smp) and more ram (-m).&lt;/p&gt;

&lt;h2&gt;Bugs&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;The hack I used to get it to boot under QEMU with SMP is obviously not a good solution.  The problem may well lie with QEMU not with Plan 9 and I need to investigate more thoroughly.&lt;/li&gt;
&lt;li&gt;Probably related, but it does not boot under QEMU with more than 8 CPUs.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ueber.net/who/mjl/plan9/plan9-obsd.html"&gt;Running a Plan 9 network on OpenBSD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mirtchovski.com/lanlp9/network/fs.html"&gt;Fileserver setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.cua0.org/post/3828150848</link><guid>http://blog.cua0.org/post/3828150848</guid><pubDate>Sun, 13 Mar 2011 10:30:27 +0100</pubDate><category>floppy</category><category>CPU</category><category>server</category><category>QEMU</category><category>plan 9</category></item><item><title>Dealing bridge hands</title><description>&lt;p&gt;Last night I wrote a little program to deal random bridge hands.  It does a Knuth shuffle using /dev/random as the RNG, sorts each player&amp;#8217;s hand, and then prints them out.  It can either pretty print the hands or output in PBN.  It&amp;#8217;s not terribly fast due to /dev/random, which is limited to a few hundred bits a second, but consequently it should generate pretty good deals.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s written for &lt;a href="http://plan9.bell-labs.com/plan9"&gt;plan 9&lt;/a&gt; but it should compile easily under &lt;a href="http://swtch.com/plan9port/"&gt;plan 9 port&lt;/a&gt; using 9c and 9l.&lt;/p&gt;

&lt;script src="https://gist.github.com/857165.js?file=bdeal.c"&gt;&lt;/script&gt;</description><link>http://blog.cua0.org/post/3684743355</link><guid>http://blog.cua0.org/post/3684743355</guid><pubDate>Sun, 06 Mar 2011 20:32:00 +0100</pubDate><category>PBN</category><category>bridge</category><category>random</category><category>plan 9</category></item><item><title>Café à l'eau froide</title><description>&lt;p&gt;Je viens d&amp;#8217;écrire &lt;a href="http://www.cua0.org/publications/misc/cafe_froid.pdf"&gt;un article&lt;/a&gt; sur le café à l&amp;#8217;eau froide, une nouvelle technique pour préparer le café qui a des caractéristiques intéressantes. L&amp;#8217;article explique ce que j&amp;#8217;ai fait pour faire le café en utilisant l&amp;#8217;aeropress et présente d&amp;#8217;ailleurs mes réfections sur la méthode en général.&lt;/p&gt;</description><link>http://blog.cua0.org/post/3524334386</link><guid>http://blog.cua0.org/post/3524334386</guid><pubDate>Sat, 26 Feb 2011 16:59:00 +0100</pubDate><category>coffee</category><category>cold</category><category>brewing</category><category>technique</category></item><item><title>Hosting venti arenas on Amazon S3</title><description>&lt;p&gt;I&amp;#8217;ve been using Amazon&amp;#8217;s S3 storage service for some critical backups.  Namely these are things I think are worth having an off-site backup for in case of fire/theft/stupidity, such as my collection of photos (I don&amp;#8217;t backup scans as they are too big, and I can scan them again probably).  I started off using s3fuse for accessing s3 buckets, and this worked ok.  Sadly, it does have some disadvantages such as leaving the management of incrementals etc. completely up to you.  There are other bits of software such as &lt;a href="http://duplicity.nongnu.org/"&gt;duplicity&lt;/a&gt; that bundle things into tar filed, do incremental backups, and upload to s3 buckets, but this style of backup is far too painful and error prone (think &lt;a href="http://www.bacula.org"&gt;Bacula&lt;/a&gt;).  Also I had some weird problems with rsync.&lt;/p&gt;

&lt;p&gt;What I really wanted was a venti server backed by s3, and lo and behold &lt;a href="http://9fans.net/archive/2008/02/343"&gt;somebody else&lt;/a&gt; already had the idea.  Thanks to this marvellous work we can simply setup the s3 backed arenas and start vac(1)ing.&lt;/p&gt;

&lt;p&gt;After fetching the s3venti from sources I found it didn&amp;#8217;t compile on my p9p installation.  Luckily the patch was trivial:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ventidat.h:
134a135
&amp;gt;   VtMaxLumpSize = 65536,
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After that everything compiled and seems to be working mostly perfectly.  I did discover however that EU hosted buckets don&amp;#8217;t work.  It&amp;#8217;s not too critical but if I have time I&amp;#8217;ll dig into it a bit further and write a patch.&lt;/p&gt;</description><link>http://blog.cua0.org/post/3341421113</link><guid>http://blog.cua0.org/post/3341421113</guid><pubDate>Thu, 17 Feb 2011 08:00:07 +0100</pubDate><category>amazon</category><category>s3</category><category>venti</category><category>backup</category></item><item><title>Aligning time-series</title><description>&lt;p&gt;Recently I wanted to align some time-series data recently for plotting.  I couldn&amp;#8217;t find some library function in R to do it for me (actually I did, but they involved stuffing around with special time series objects instead of vectors), and the problem was interesting anyway so I wrote something myself.  The idea is to find the offset using cross-correlation and then do a phase shift to align.  This can all be done in the frequency domain, where the cross-correlation is just the Hadamard product between the Fourier components of the signal to align with the conjugate of the reference[1].&lt;/p&gt;

&lt;script src="https://gist.github.com/828991.js?file=gistfile1.r"&gt;&lt;/script&gt;&lt;p&gt;there&amp;#8217;s two align function, align2() aligns a pair of signals with x as the reference and align() aligns the columns of a matrix.  There&amp;#8217;s a bunch of padding added for the Fourier transform so the final vectors will contain leading and trailing zeros.  The plotting function removes these.  Here&amp;#8217;s an example, unaligned:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lgpb0lktu21qg9u7s.png" alt="unaligned"/&gt;&lt;/p&gt;

&lt;p&gt;and aligned:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lgpb0uManF1qg9u7s.png" alt="aligned"/&gt;&lt;/p&gt;

&lt;p&gt;[1] Semi-cute but well known, reversing the Fourier coefficients of a real signal reduces to calculating the complex conjugate.  As an ordinary convolution in the frequency domain is x ⊗ y, the cross-correlation is thus x ⊗ y̅.&lt;/p&gt;</description><link>http://blog.cua0.org/post/3324273287</link><guid>http://blog.cua0.org/post/3324273287</guid><pubDate>Wed, 16 Feb 2011 09:26:00 +0100</pubDate><category>time-series</category><category>aligning</category><category>Fourier</category><category>R</category></item><item><title>Script for creating p9p venti stores</title><description>&lt;p&gt;Recently I wanted to setup a &lt;a href="http://en.wikipedia.org/wiki/Venti"&gt;venti&lt;/a&gt; server backed by a USB disk drive.  The drive already has a filesystem so I didn&amp;#8217;t want to repartition it (resizing XFS is a pita), and in any case running venti from files has some advantages.  It isn&amp;#8217;t completely trivial as the arenas, log, and bloom filter spaces have to all be created manually.  I found a script on the internet, but it wasn&amp;#8217;t exactly what I was after, so I rewrote it slightly for my purposes.  Here it is:&lt;/p&gt;

&lt;script src="https://gist.github.com/824666.js?file=mkventi"&gt;&lt;/script&gt;&lt;p&gt;it&amp;#8217;s run like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkventi &amp;lt;arena size&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where size is in MB.  It&amp;#8217;ll create a log with 5% of the arena size and a bloom filter of 512MB (note the bloom filter could be a lot smaller, but I&amp;#8217;m working with 500GB disks).  Afterwards it should be sufficient to run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;venti/venti -c venti.conf.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to start the venti server.&lt;/p&gt;</description><link>http://blog.cua0.org/post/3309760252</link><guid>http://blog.cua0.org/post/3309760252</guid><pubDate>Tue, 15 Feb 2011 16:18:00 +0100</pubDate><category>venti</category><category>p9p</category></item></channel></rss>

