<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>lbrandy.com</title>
	
	<link>http://lbrandy.com/blog</link>
	<description>{ on programming and the internets, every monday }</description>
	<lastBuildDate>Mon, 08 Mar 2010 03:47:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/lbrandy" /><feedburner:info uri="lbrandy" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Non-programming books for programmers: The Selfish Gene</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/bZqKnNHzDq8/</link>
		<comments>http://lbrandy.com/blog/2010/03/non-programming-books-for-programmers-the-selfish-gene/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 03:47:58 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1249</guid>
		<description><![CDATA[ 
My wife loves fiction. It&#8217;s not my thing. I&#8217;ve tried, but I struggle to read fiction. There are some novels that I&#8217;ve heard are beloved by my fellow programmers (Cryptonomicon for one), and I&#8217;d love to hear any other suggestions along this line.
For me, though, my heart belongs to nonfiction. Especially science. One book, [...]]]></description>
			<content:encoded><![CDATA[<div style="float:left;margin-right:20px;"> <iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=lbrandycom-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0199291152" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></div>
<p>My wife loves fiction. It&#8217;s not my thing. I&#8217;ve tried, but I struggle to read fiction. There are some novels that I&#8217;ve heard are beloved by my fellow programmers (<a href="http://www.amazon.com/gp/product/0060512806?ie=UTF8&amp;tag=lbrandycom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0060512806">Cryptonomicon</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lbrandycom-20&amp;l=as2&amp;o=1&amp;a=0060512806" border="0" alt="" width="1" height="1" /> for one), and I&#8217;d love to hear any other suggestions along this line.</p>
<p>For me, though, my heart belongs to nonfiction. Especially science. One book, in particular, stands above the rest. I&#8217;ve read <a href="http://www.amazon.com/gp/product/0199291152?ie=UTF8&amp;tag=lbrandycom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0199291152">The Selfish Gene</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lbrandycom-20&amp;l=as2&amp;o=1&amp;a=0199291152" border="0" alt="" width="1" height="1" />, by Richard Dawkins, twice and, for me, it&#8217;s quite simply the most interesting book I&#8217;ve ever read.</p>
<h3>If you haven&#8217;t read it&#8230;</h3>
<p>If you are anything like me (a programmer and general science nerd) and you haven&#8217;t read it, this is approximately what you&#8217;ll be thinking:</p>
<blockquote><p>I understand evolution pretty well, and I don&#8217;t really need to read a book to understand evolution. Besides, evolution is kind of boring &#8212; the fittest survive, and pass on their genes, problem solved. I&#8217;d rather read about physics.</p></blockquote>
<p style="text-align: right;">&#8212;<strong>me (and maybe you), before reading</strong></p>
<p>Let me try to put into words how wrong this was. First, and foremost, this book made me realize how absolutely little I&#8217;ve actually thought about evolution, and how absolutely fascinating evolutionary biology is. <strong>This book is basically a series of mental experiments to explain the biological world through game theory.</strong> The organisms are playing a giant game, and those with the best strategies will survive. Please note that the &#8220;best&#8221; strategies often depend on what strategies everyone else is using. Therefore, a population will then tend towards evolutionary stable mixes of strategies. You will have repeated WTF moments as he makes the most unintuitive animal behaviors (ie, strategies) suddenly make perfect sense.</p>
<p>Second, let me say, that as a programmer, you have a VERY UNIQUE perspective that makes evolutionary biology (and the arguments in the book) extremely fascinating (more on this in a bit). Last, and maybe most importantly, for me, it is fairly safe to say that if I had read this book in high school, instead of recently, I&#8217;d probably have become an evolutionary biologist, and not a programmer. It was that interesting.</p>
<h3>A quick overview</h3>
<p>In the book, Richard Dawkins basically argues for an evolutionary understanding from a &#8220;gene&#8217;s eye view&#8221;. In other words, everything in evolution makes sense if you think of genes as the unit of selection, and not individuals nor groups. Most of the book is set against the backdrop of Dawkins arguing against a competing theory known as <a href="http://en.wikipedia.org/wiki/Group_selection">group selection</a>. Now, I am no evolutionary biologist, so I&#8217;m not going to weigh in too much on who is right (as I understand it, Dawkins is &#8220;mostly&#8221; right but there is some controversy at the edges), but the book itself makes so many fascinating arguments that it&#8217;s worth the read for that alone.</p>
<p>It is amazing how much the gene&#8217;s eye view of the problem changes the game. It can, to some extent, put your life into perspective. From a gene&#8217;s perspective, keeping you alive until you reproduce is a good thing. Keeping you alive for too long after is a bad thing, because you are now competition for your children. <strong>You are nothing but a survival mechanism built for and by your genes. </strong><strong>A</strong><strong>t some point, your genes would prefer if you&#8217;d just die.</strong></p>
<p>Certain behaviors are, seemingly, difficult to explain from a naive understanding of the theory of evolution. The primary one (one that is discussed at length) is altruism in the animal kingdom. It would seem that given the whole survival of the fittest thing, altruism would usually be a bad idea. Dawkins argues extensively, using numerous examples, of exactly how altruism helps particular genes reproduce. Or, and more to the title, how &#8220;selfish&#8221; actions by a gene (the gene looking out for only itself) leads to altruistic actions in the individual.</p>
<h3>A giant exercise in game theory</h3>
<p>Dawkins goes on to make plausible explanations for all sorts of phenomonan that you&#8217;ve probably never even considered as requiring an explanation. Here&#8217;s a great example: you might be able to think of a good evolutionary explanation for why sexual reproduction came about (Dawkins gives you the usual reason, if you can&#8217;t), <strong>but can you think of a sound reason why nature settled on two sexes?</strong> Why not just one (anyone can mate with anyone?) Why not three? Or Four? The answer Dawkins gives is a bit speculative, but fascinatingly plausible. <em>[note: much of the book is Dawkins' summary of other people's work on these various issues... I don't want to give the impression that all of these discussions are his original work]</em></p>
<p>The basic argument goes as follows. In the beginning of sexual reproduction among early organisms, all sex cells were basically the same. This meant any pair of sex cells could merge and become a new organism (ie, there was just one sex). Larger sex cells had an advantage over smaller ones, as it started the new organism off with a larger food supply. Over time, these cells get bigger, last longer, and are more well protected. These large sex cells are increasingly expensive to produce, but they provide the future offspring with the best start. This opens up the gene pool to exploitation from a &#8220;selfish&#8221; strategy. If you could produce extremely small, extremely cheap sex cells in large numbers, you could mate and piggyback on the &#8220;expensive&#8221; large sex cells. So some organisms began flooding the area with these cheap cells, and succeeding by piggybacking. And from here, the two types of organisms continue to diverge, generating the two sexes we see today.</p>
<p>So while you might argue that an all-female population would be more successful (because the males are &#8220;cheating&#8221;), an all-female population is inherently unstable. A single male introduced to this all-female world will succeed at reproducing at an alarming rate (note: this argument takes place long before animals had the ability to properly &#8220;choose&#8221; their mate, and this &#8220;choosing&#8221; and it&#8217;s impact on evolution are discussed at length, with amazing results). <strong>Evolution is not creating the most fit populations, but the most stable.</strong></p>
<p>This, by the way, forms the genesis of all sorts of sex-related differences seen throughout the animal kingdom: monogous preferences from females, promiscuity from males, male competition for females (in winner-take-all harem-like arrangements), and so on. And here&#8217;s an interesting follow-up: if one male can produce enough sex cells for multiple females, what is the optimal sex ratio? Almost all animals hover around 50/50, but why? Why couldn&#8217;t, for example, 75% female, 25% male work? Dawkins tries to explain this too!</p>
<h3>Abstract evolution</h3>
<p>The arguments made in the book just appeal right to the core of a computer programmer who is constantly thinking in optimizations, algorithms, and mathematics. As I said before, the entire book really reads as an attempt to explain various natural phenomenon through a combination of game theory, and the world of the genes. As a computer scientist, you cannot help but see yourself writing programs to test ideas that Dawkins puts forward. You cannot help but see the parallels in Dawkins arguments to computer algorithms. When Dawkins discusses, briefly, how computer programming is a secret passion (he might say vice) of his, you will immediately understand it &#8220;from the other side&#8221;. The two disciplines are so incredibly similar. For the exact same reason I am drawn to his arguments, he is drawn into computer science. The two fields have such interesting mental overlap.</p>
<p>The most fascinating take away from the book is a view of evolution not as a property intrinsic to life, but as an emergent property of certain types of systems. <strong>Perhaps most famously, this is the book that Richard Dawkins invents the word </strong><a href="http://www.youtube.com/watch?v=oHg5SJYRHA0"><strong>meme</strong></a>. A meme, in his context, is an &#8220;organism&#8221; that spreads not through the natural world, but in our own minds. In other words, memes are ideas, and some are more fit to &#8220;reproduce&#8221; from brain to brain. These memes exist in an enviornment (our culuture, history, morals, and so on), and adapt as necessary to continue surviving.</p>
<p>I&#8217;m less fascinated by memes themselves as I am about what memes represent. The existance of memes is basically Dawkins&#8217; way of saying that evolution is an emergent property of a certain type of system. It follows directly from a set of axioms: given some form of descent with modification, and some non-random selection of those descendants, t<strong>hen evolution not only will happen, but must happen.</strong> Any system that fits that requirement will have evolution occurring. These systems will strive towards &#8220;organisms&#8221; that are stable within their &#8220;environment&#8221;. In other words, evolution is not just a theory of life but a direct and unavoidable consequence of the rules of the game.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/bZqKnNHzDq8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2010/03/non-programming-books-for-programmers-the-selfish-gene/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2010/03/non-programming-books-for-programmers-the-selfish-gene/</feedburner:origLink></item>
		<item>
		<title>Parallel programming is hard. Right?</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/iQrCsmNo0cw/</link>
		<comments>http://lbrandy.com/blog/2010/02/parallel-programming-is-hard-right/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:07:39 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1227</guid>
		<description><![CDATA[It&#8217;s a fairly oft-repeated mantra of programmers. Parallel programming is hard. Right? Right! Almost everyone will tell you so! I was at a job fair not too long ago and even one of the students told me so. Everyone knows parallel programming is hard.
Sadly, though, I disagree with the vast majority on why. The most [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a fairly oft-repeated mantra of programmers. Parallel programming is hard. Right? Right! Almost everyone will tell you so! I was at a job fair not too long ago and even one of the students told me so. Everyone knows parallel programming is hard.</p>
<p>Sadly, though, I disagree with the vast majority on why. The most common answer, by far, will involve some combination of the following words: <a href="http://en.wikipedia.org/wiki/Deadlock">deadlock</a>, <a href="http://en.wikipedia.org/wiki/Deadlock#Livelock">livelock</a>, <a href="http://en.wikipedia.org/wiki/Parallel_programming#Race_conditions.2C_mutual_exclusion.2C_synchronization.2C_and_parallel_slowdown">synchronization</a>, <a href="http://en.wikipedia.org/wiki/Shared_memory">shared memory</a>, <a href="http://en.wikipedia.org/wiki/Race_conditions">race condition</a>, <a href="http://en.wikipedia.org/wiki/Thread_safety">thread safety</a> and so on. You can find umpteen blog posts explaining how difficult it is to avoid race conditions, and how <a href="http://lbrandy.com/blog/2009/02/bugs-of-doom-aka-the-heisenbugs/">some of the most pernicious bugs come from synchronization issues</a>. Yes, indeed.</p>
<p>(note: this post is mostly about data-parallel programming, or other parallel optimizations for computational performance purposes. There are other reasons to use concurrency, but I&#8217;m not sure my argument will hold in most of those cases.)</p>
<h3>Avoiding race conditions is hard, but it&#8217;s not that hard.</h3>
<p>There, I said it. I think most people, especially those who&#8217;ve only learned about parallel programming in a classroom setting, believe that race conditions, synchronization, and dead-locks are the crux of the parallel programming problem. There are a whole bunch of really solid reasons for me to say they are wrong:</p>
<ol>
<li> You can almost always use a simple locked data-structure for synchronization fairly painlessly (and with a bit of practice, you can usually write one fairly painlessly, too).</li>
<li>You can almost always abstract away the synchronization primitives and unit-test them really well.</li>
<li>There are tons of good off-the-shelf and well-tested synchronization libraries for most platforms, and most languages.</li>
<li>The <a href="http://www.mysql.com/">truly difficult synchronization problems</a> have many, many smart people working on them, and these are things you should not be reinventing.</li>
<li><strong>And last but not least, and most importantly, no matter how difficult your synchronization issues are, I can assure you that bigger problems are lurking.</strong></li>
</ol>
<h3>Why parallel programming is actually hard</h3>
<p>There is probably no one correct answer to this question, but most will probably involve words like: granularity, throughput, response-time, cache size, memory bottleneck, and so on.</p>
<p>Let&#8217;s start with the core of the problem: <a href="http://en.wikipedia.org/wiki/Granularity">granularity</a>. When parallelizing some computation, you must decide &#8220;at what level&#8221; to parallelize the problem. Choosing the correct granularity is almost never immediately obvious and, almost always, there is more than one correct answer.  Trade-offs abound.</p>
<p>I&#8217;ll invoke a problem from my daily work that will help explain this nicely. A video file is nothing but a sequence of images. If you want to perform face detection on a video stream, you can parallelize in several ways. A coarse grain approach might be to give each worker its own image, and collect the results at the end. A finer grained approach might throw all of the threads at a single image hoping you can process that image n-times faster.</p>
<p><strong>Here are some general (yet frequently broken) rules of thumb:</strong></p>
<p>1. <strong>Finer grained algorithms will thread less efficiently than coarse grained.</strong> Usually, it&#8217;s because any natural parallelism in your problem tends to improve as you become more coarse grained (do 20 images in each thread, instead of one). Furthermore, coarse grained algorithms do less communication and synchronization per unit of work. This means coarse grain approaches will tend to have better throughput (work done per unit of time) and less administrative overhead. There is an important caveat here, if you are too coarse grained, or if your jobs vary in size too much, you run smack into <a href="http://en.wikipedia.org/wiki/List_of_NP-complete_problems#Sequencing_and_scheduling">scheduling problems</a> that will certainly leave some workers with nothing to do.</p>
<p>2.<strong> Finer grained algorithms will have better response times.</strong> In this case, response time means from submission of a work unit, until the result is ready. Since a fine grained algorithm is more frequently synchronizing the state, you have more opportunities to prioritize things that need to get done, and then declare them done.</p>
<p>3. <strong>Finer grained algorithms will tend to use less cache/memory.</strong> This is because, in general, less data being worked on.</p>
<p>4. <strong>Finer grained problems tend to be more painful to maintain</strong>. You will assume parallelism along some dimension that really needs to be serialized for some new feature.</p>
<p>Let&#8217;s go back to my real-world example. Sometimes throughput is king, like when you are processing a movie file. In this scenario, sending a frame to each worker thread and collecting the results later is fairly easy to implement, and threads extremely well. Other times, response time is king. For example, when tracking a face with a pan-tilt-zoom camera. Sending each frame to a different worker is completely inappropriate for this use-case because this doesn&#8217;t improve response time at all (each thread only has one worker, still). As soon as a frame is submitted, you need an answer as quickly as possible to have stable control. In this case, it is far better to throw all of the worker threads at a single frame (thread at the sub-frame level), and hope to improve the computation of a single frame.</p>
<p>So what do you do when the frame-level approach threads more efficiently than the sub-frame level treading? Well, you&#8217;ve run into a situation where one approach is better for throughput, and the other for response time. If you want to support both use-cases, you need both approaches (and some good documentation!). I think this demonstrates my original point that bigger problems than synchronization are lurking. No matter how difficult your synchronization problems are, I just doubled them.</p>
<h3>Trade-offs in every direction</h3>
<p>So lets say you can sort your way through that nest of trade-offs to find a place that gives you the right balance of response-time and throughput, stays within your memory requirements, and threads at an acceptable efficiency, you are home free! Right? Wrong. Now add in the fact that you cannot predict the future, and you don&#8217;t know what features will be needed (and what will then need to be serialized), how your response-time vs throughput needs might change, or how you will ever maintain this mess.</p>
<p>If you&#8217;ve survived this far, just remember the computer has one last trump card to play on you. All of these threads run on all real machines, with real memory bandwidths, real caches, connected over networks with fixed bandwidth. Each of these constraints has the ability to trip up your beautifully parallel problem and make it painfully serial. Let&#8217;s not even mention the idea that it might need to run on different machines with different capabilities.</p>
<p>In truth, all of these difficulties come from the same source. Mapping a non-trivial problem onto a parallel machine optimally borders on the impossible when you fully consider all of the different requirements along all of the different dimensions.</p>
<p>And so here we are. When I think of parallel programming, synchronization is difficult, but managable. It is not, however, what makes parallel programming hard.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/iQrCsmNo0cw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2010/02/parallel-programming-is-hard-right/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2010/02/parallel-programming-is-hard-right/</feedburner:origLink></item>
		<item>
		<title>On Debt Collectors</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/Ue93iH6MCjo/</link>
		<comments>http://lbrandy.com/blog/2010/02/on-debt-collectors/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 15:46:55 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1223</guid>
		<description><![CDATA[When I moved to Pittsburgh, I got a new cellphone number. I traded in the lackluster views of my 850 area code for the it-is-what-it-is 412. From almost the very first day of having this new cellphone number, I began receiving calls for a guy named Paul. In the beginning, people would apologize. Some people, however, started asking [...]]]></description>
			<content:encoded><![CDATA[<p>When I moved to Pittsburgh, I got a new cellphone number. I traded in the <a href="http://images.google.com/images?&amp;q=emerald%20coast">lackluster views</a> of my 850 area code for the it-is-what-it-is 412. From almost the very first day of having this new cellphone number, I began receiving calls for a guy named Paul. In the beginning, people would apologize. Some people, however, started asking me weird questions. Like what my name was, and if I knew any Pauls.</p>
<p>Over time I began to realize that Paul, and my phone number, were in the hands of debt collectors. I would receive a dozen calls in a week and one by one be forced to tell each collector that I was not Paul, I was never Paul, and they needed to stop calling me. Most were polite, some were not. At first, the aggressive ones were fun to deal with. Several people tried to tell me I was covering for Paul, or I was lying about not being Paul. Some would ask me my name, which I never gave (replace Paul&#8217;s name with mine? Oh god.), and this seemed to really piss some of them off. After a month or so of dealing with these calls, I&#8217;d end up off of most lists, and the calls would stop. A few months later, presumably after the bad debt had been sold to the next round of collectors, the cycle would start up again. This has been going on for almost 5 years although I admit that each outbreak of this debt collector herpes is less severe than the last.</p>
<p>I found out quite a bit about Paul through debt collectors. One told me I&#8217;d end up in jail&#8230; again. I asked if he knew what a debtor&#8217;s prison was, and he didn&#8217;t. Another told me to stop buying drugs so I could pay my debts. A third told me that I&#8217;d lose my third job this year if I didn&#8217;t pay. I have no idea how much of this is true, of course. It should be noted that the fact that I am not Paul, it is actually <a href="http://en.wikipedia.org/wiki/Fair_Debt_Collection_Practices_Act">fairly illegal for these debt collectors to reveal anything to me about Paul</a>. But reveal they did. It&#8217;s hard to say which of these were true, and which were tactics. I have reason to believe at least one of them was just making shit up completely.</p>
<p>But not everything was made up. I know Paul&#8217;s full name. I know his (former?) address. I know his occupation(s). I know several of his friend&#8217;s names. I was dealing with people that were not scrupulous at all. On more than one occasion I had to bust out the Fair Debt Collections regulations (or at least bluff my way through them) because of some asshat on the phone trying to bully me into admitting I was really Paul. Or trying to get me to pay for Paul&#8217;s debts so that the calls would stop. And so on.</p>
<p>About a month ago, all of this changed. I started receiving calls from probate and estate &#8220;people&#8221; (they thought of themselves as legal professionals, but to me there were more like debt collectors for dead people). You see, apparently Paul had died. And apparently the probate people don&#8217;t quite have the same set of rules that the debt collector people have because they told me quite a bit more about Paul.</p>
<p>Paul had a shitty life, it appears. It is, of course, hard to tell given that my only information about Paul is through debt collectors. Maybe Paul faked his own death to get away from all of these assholes. He is, hopefully, living on a boat on the keys. If not, rest in peace, man.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/Ue93iH6MCjo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2010/02/on-debt-collectors/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2010/02/on-debt-collectors/</feedburner:origLink></item>
		<item>
		<title>Me and my slides</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/TVixIX0AB20/</link>
		<comments>http://lbrandy.com/blog/2010/01/me-and-my-slides/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 21:58:11 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1217</guid>
		<description><![CDATA[I am cursed with either high expectations or awful slide making skills.

This graph is actually only partially correct (I don&#8217;t have until October to get it right). It leaves out the cycles where I add 10 slides in a half hour, then spend the next 3 hours rewording and reworking them until only 1 and [...]]]></description>
			<content:encoded><![CDATA[<p>I am cursed with either high expectations or awful slide making skills.</p>
<p><img class="alignnone size-full wp-image-1218" title="slides" src="http://lbrandy.com/blog/wp-content/uploads/2010/01/slides.png" alt="slides" width="532" height="277" /></p>
<p>This graph is actually only partially correct (I don&#8217;t have until October to get it right). It leaves out the cycles where I add 10 slides in a half hour, then spend the next 3 hours rewording and reworking them until only 1 and a half are left. And then I repeat that cycle a few more times.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/TVixIX0AB20" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2010/01/me-and-my-slides/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2010/01/me-and-my-slides/</feedburner:origLink></item>
		<item>
		<title>My New Year’s Resolution</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/K4J20H7YcjM/</link>
		<comments>http://lbrandy.com/blog/2010/01/my-new-years-resolution/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 14:27:43 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1197</guid>
		<description><![CDATA[I am a bit of a procrastinator.
Yes, yes, that doesn&#8217;t exactly make me special, but I&#8217;m talking specifics here. I&#8217;m a programmer, and a procrastinator. And that can mean troubles.
For the next year (and/or the first three weeks of January, whichever comes first), I&#8217;m going to automate/refactor/abstract any operation I do for the third time. I&#8217;ve noticed [...]]]></description>
			<content:encoded><![CDATA[<p>I am a bit of a procrastinator.</p>
<p>Yes, yes, that doesn&#8217;t exactly make me special, but I&#8217;m talking specifics here. I&#8217;m a programmer, and a procrastinator. And that can mean troubles.</p>
<p>For the next year (and/or the first three weeks of January, whichever comes first), I&#8217;m going to automate/refactor/abstract any operation I do for the third time. I&#8217;ve noticed far too many insignificant hiccups in my workflow that go ignored. It&#8217;s just that the marginal cost of putting up with the annoyance is so much less painful than sitting down and writing the script (or a special commands, or option, or what have you). Maybe I&#8217;ll do it next week. And next week becomes next month. And now I&#8217;ve started to realize niggling annoyances that have gone on for years. Yes, years.</p>
<p>Let me give you two examples&#8230;</p>
<h3>Oprofile</h3>
<p>I use oprofile constantly.</p>
<pre>sudo opcontrol --reset
sudo opcontrol --start
./run_my_code
sudo opcontrol --shutdown
opreport -lt1</pre>
<p>I&#8217;ve typed that out, in full, for probably close to 3 years now. Why? Other people have noticed. I&#8217;ve noticed. I&#8217;m pretty sure no less than two of my co-workers would have edited my aliases for me, if I had let them. Well, I finally sat down and wrote the 10 line python script that will do this (and a handful of other useful oprofile functions) for me. It took about 10 minutes. Sigh.</p>
<h3>Emacs vs vi</h3>
<p>I&#8217;ve always been an emacs fan. I probably always be. However, there is one part of vi that has always made me jealous. The name. <code>vi</code> is just such an amazingly easy name to type instead of the incredibly laborious <code>emacs</code>. As a young kid, I decided to fix this and I added an alias for my customized emacs launch as &#8220;<code>em</code>&#8220;. Yes, I aliased emacs to <code>em</code>. I&#8217;ve been using it for years. And it&#8217;s extremely stupid. Extremely, extremely stupid. <a href="http://en.wikipedia.org/wiki/Rm_(Unix)">It doesn&#8217;t take much thought to figure out why &#8220;<code>em important_file.cpp</code>&#8221; can become a disaster.</a> (extra stupid note: compare the locations of the typo keys).</p>
<p>I know it&#8217;s stupid, and yet it continues. Every time I move my environment over to a new machine, I copy the alias over. Why? Because it&#8217;s always been there, and it&#8217;s on all my machines. Because I can&#8217;t fix it <i>right now</i>. I&#8217;ll fix it next time. Gah. It ends now. I will never type <code>em</code> again.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/K4J20H7YcjM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2010/01/my-new-years-resolution/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2010/01/my-new-years-resolution/</feedburner:origLink></item>
		<item>
		<title>Inspiration vs Distraction</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/ADs5Y731dZo/</link>
		<comments>http://lbrandy.com/blog/2009/12/inspiration-vs-distraction/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 14:59:22 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1190</guid>
		<description><![CDATA[When the bug of inspiration bites, what do you do? Do you drop the old project and go for the new shiny one? Or do you ignore the urge?
I am one those of people who is constantly switching between my personal projects. I will work tirelessly on project A, and then on a certain Tuesday [...]]]></description>
			<content:encoded><![CDATA[<p>When the bug of inspiration bites, what do you do? Do you drop the old project and go for the new shiny one? Or do you ignore the urge?</p>
<p>I am one those of people who is constantly switching between my personal projects. I will work tirelessly on project A, and then on a certain Tuesday when the wind is blowing just right, I&#8217;ll suddenly lose all desire for project A and find a sudden and insatiable urge to work on project B. When inspiration strikes, it tends to be very difficult for me to ignore. <strong>My hard drive is consequently littered with half-starts, rough outlines, notes, and various ideas, bad and good, in various stages of completion. </strong></p>
<p>This brings up the interesting question as to what the preferred state of affairs is. Should I be more disciplined and learned to ignore the grass-is-always-greener syndromes, or should I go with my own fickle whims? Am I perpetually distracted by these flirtations of inspiration, or is this, in some way, healthy? Given that I almost always chose to drop the old clunker and work on the new thing, you could certainly read into my character quite a bit, if you wanted. Maybe I am too fickle. Maybe I am easily distracted. Maybe I&#8217;ll never actually accomplish any of these things. Maybe. I see it another way.</p>
<p>Most projects get exactly one burst of effort before permanent abandonment. Some problems though, I find myself coming back to time and again. I view this particular mechanism as healthy. It&#8217;s a natural selection of my ideas. May the fittest survive. This is why I don&#8217;t really feel guilty for dropping yet-another half-started project and starting something new.<strong> If the idea survives a few months off, it&#8217;s probably worth keeping.</strong> If it doesn&#8217;t, so be it.</p>
<h3>Embrace the distraction</h3>
<p>So in that vein, I&#8217;ve put on hold several slightly boring personal projects for a shiny new one.<strong> I&#8217;m writing a game.</strong> Oh this will end well. I&#8217;ve spent the last three weekends tearing apart the <a href="http://udk.com/">UDK</a> to learn how it works and over that time I&#8217;ve put together this spectacularly early prototype:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="340" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/DZ-gov94_po&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="560" height="340" src="http://www.youtube.com/v/DZ-gov94_po&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>So here&#8217;s to another distraction.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/ADs5Y731dZo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2009/12/inspiration-vs-distraction/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2009/12/inspiration-vs-distraction/</feedburner:origLink></item>
		<item>
		<title>Unplanned planning</title>
		<link>http://feedproxy.google.com/~r/lbrandy/~3/AAdjri-gB1I/</link>
		<comments>http://lbrandy.com/blog/2009/12/unplanned-planning/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 13:36:50 +0000</pubDate>
		<dc:creator>louis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lbrandy.com/blog/?p=1176</guid>
		<description><![CDATA[Here are some rectangles:
struct irect {int   top; int   bot; int   left; int   right;};
struct frect {float top; float bot; float left; float right;};
Now, given those rectangles, you are asked to write a conversion from irect to frect.
struct frect convert (struct irect i) {
   struct ans = {(float) i.top, [...]]]></description>
			<content:encoded><![CDATA[<p>Here are some rectangles:</p>
<pre>struct irect {int   top; int   bot; int   left; int   right;};
struct frect {float top; float bot; float left; float right;};</pre>
<p>Now, given those rectangles, you are asked to write a conversion from <code>irect</code> to <code>frect</code>.</p>
<pre>struct frect convert (struct irect i) {
   struct ans = {(float) i.top, (float) i.bot, (float) i.left, (float) i.right)};
   return ans;
}</pre>
<p>This might at first seem like a reasonable answer but&#8230; it&#8217;s almost certainly not.</p>
<h3>The problem</h3>
<p>What is the area of a rectangle with corners (0.0,0.0) and (10.0,10.0)?</p>
<p>Now, how many pixels are in an image with bounds (0,0) to (10,10)?</p>
<p>Hopefully, your answers disagreed (or at least you can see how they could disagree). In our field, we deal with images. Lots and lots of images. One of the most fundamental data structures you can possibly imagine when dealing with images is the lowly rectangle. For us, a rectangle is a region of an image. And it’s this role, as a region, that creates all kinds of pain and heartache.</p>
<p>We can more clearly isolate the problem by asking what is the lower-right hand corner of the above integer rectangle? Well, it depends on exactly what we mean by the lower-right hand corner. If you want to know where to look in memory for the lower-right hand corner pixel information, the answer is (x=10,y=10). If you wanted to know the Cartesian coordinate of the true lower right-hand corner, the answer would be (x=11, y=11).</p>
<h3>The solution?</h3>
<p>The difficulty here is the conflation of two separate ideas into the same form. First we have the integerized “point” on the cartesian plane, and then we have the 1&#215;1 region known as a “pixel” and specified by its index. How should pixel indices convert to the cartesian plane? Put another way, should an integer rectangle (0,0)x(10&#215;10) have an area of 100 or 121? This is, to some extent, a question of convention. If you pick one, and are consistent, everything will work out fine. However, almost certainly, for your application, one convention will result in cleaner code.</p>
<p><strong>So the answer to the original question becomes a fairly complicated ordeal.</strong> This one problem only scratches the surface of the painstaking care that must be taken when dealing with integer and floating point regions of pixels. You would need to figure out exactly how and why you use rectangles and what index convention you want to use. For every function that you write operating on rectangles, you need to carefully consider the implications of your chosen convention. And depending on the convention you use, the rest of your code is going to look very different.</p>
<p>Writing a rectangle class <em>seems</em> straightforward. Yet, all planning in the world won&#8217;t prepare you because it’s almost impossible to anticipate this design issue. It&#8217;s the simple act of trying to use one of your converted rectangles that makes the problem obvious. Almost paradoxically, this problem, once realized, can only really be solved by meticulous and careful planning. The devil is always in the details.</p>
<img src="http://feeds.feedburner.com/~r/lbrandy/~4/AAdjri-gB1I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lbrandy.com/blog/2009/12/unplanned-planning/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://lbrandy.com/blog/2009/12/unplanned-planning/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.460 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-03-11 16:19:29 -->
