<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;A0UASH45cSp7ImA9WxNUGEo.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401</id><updated>2009-11-10T10:54:09.029-08:00</updated><title>Coding Relic</title><subtitle type="html">Random musings on software in an embedded world.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://codingrelic.geekhold.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>58</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/CodingRelic" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;A0UGQX85fyp7ImA9WxNUGEs.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-4329324568218475678</id><published>2009-11-10T08:07:00.000-08:00</published><updated>2009-11-10T08:07:00.127-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-10T08:07:00.127-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="architecture" /><title>Ethernet Integrity, or the Lack Thereof</title><content type="html">&lt;p&gt;Have you heard any variation of this claim?&lt;/p&gt;

&lt;div style="padding: 5px 10px 5px 10px; border-width: 1px; border-color: #aaa; border-style: solid; background-color: #eee; margin: 1em 5em 1em 4em;"&gt;We don't need our own integrity check. The TCP checksum is pretty weak, but Ethernet uses a ludicrously strong CRC. Even if you don't trust the TCP checksum, Ethernet will detect any errors.&lt;/div&gt;

&lt;p&gt;Let's dig into this a bit, shall we?&lt;/p&gt;

&lt;p&gt;&lt;img alt="Ethernet switch diagram" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/Svb9kHe9fsI/AAAAAAAAAi4/FEMd6FcivjQ/s320/switch.png" align=right style="border: 0px; padding: 3px;" title="So much trouble for so few bits" width="218" height="251" /&gt;A modern switch fabric chip is designed for both L2 ethernet switching and L3 IP routing. The additional logic for IP routing adds relatively little area in modern silicon technologies, while not having a routing capability would put them at a competitive disadvantage. Essentially all ethernet fabric chips, even those inside relatively cheap L2 switches, have the design features to route IPv4 traffic to at least a basic degree.&lt;/p&gt;

&lt;p&gt;When a packet arrives at the input port (A) its CRC will be checked and the packet discarded if corrupt. If the packet is destined to the router's MAC address, its destination IP address will be looked up for L3 routing (C). An L3 router modifies the packet as part of its function, by decrementing the IP TTL and replacing the L2 destination with that of the next hop. Therefore a fresh CRC has to be regenerated at egress.&lt;/p&gt;

&lt;p&gt;Even if the packet is to be switched at L2 (B), there are cases where the packet is modified. For example server machines and switch uplinks often handle &lt;a href="http://en.wikipedia.org/wiki/IEEE_802.1Q"&gt;multiple vlans&lt;/a&gt;, so their ports will be configured for tagging (D). Addition of the vlan tag requires the packet CRC to be recalculated on egress (E).&lt;/p&gt;

&lt;center&gt;&lt;img alt="Vlan tagging" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/Svb9xDTX_rI/AAAAAAAAAjA/OsjyB4WPvro/s640/vlantag.png" style="border: 0px; padding: 3px;" title="The pastel colors remind me of a Voltron cartoon" width="416" height="157" /&gt;&lt;/center&gt;

&lt;p&gt;The point of this description? There are numerous cases at both L2 and L3 where a packet CRC cannot be preserved through the switch and will need to be regenerated at egress. ASIC designers hate special cases, as they add logic and test cases to the design. Because there are cases where the CRC &lt;i&gt;must&lt;/i&gt; be regenerated, modern switch fabrics &lt;u&gt;always&lt;/u&gt; regenerate the CRC at egress. Even if the packet has not been modified, even if the ingress CRC could have been preserved, it is discarded at ingress and regenerated at egress.&lt;/p&gt;

&lt;p&gt;It bears repeating that this is a function of the chip, not the specific product. Even the tiny ethernet switches sold for practically nothing at retail use chips which contain basic vlan tagging and IP routing features (even if that product doesn't use them), and regenerate the CRC on every packet.
&lt;img alt="5 port ethernet switch" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/Svb-Wu1CVXI/AAAAAAAAAjI/h3rQQLcOCl0/s320/cheapswitch.jpg" align=right style="border: 0px; padding: 3px;" title="Logo obscured, but you can probably figure it out" width="56" height="24" /&gt;
The fabric chip they use wasn't specifically designed for such low cost switches, there is not enough profit to justify the effort. In addition to simple L2 switches those chips can be used to build NAT appliances, as the ethernet fan-out for small wireless access points, in DSL and cable routers, for low end WAN routers, etc. When only basic L2 switching is desired these fabrics can function completely standalone without a management CPU, reducing BOM cost to the bare minimum. Addition of a CPU allows the basic L3 functions to be used in the more featureful (but still low end) products.&lt;/p&gt;


&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Impact&lt;/span&gt;
&lt;p&gt;What does this mean? The internal memories and logic paths within the switch are not covered by the ethernet CRC, it does not provide end-to-end protection. The switch might implement ECC over the whole path, but this is not common. The packet buffers are generally large enough to justify ECC, but miscellaneous FIFOs are more likely to have simple parity and logic elements often have no protection at all. It only takes one &lt;a href="http://codingrelic.geekhold.com/2009/09/soft-errors-are-hard-problems.html"&gt;soft error&lt;/a&gt; to corrupt the packet contents, and then a fresh CRC will be calculated over the corrupted data.&lt;/p&gt;

&lt;center&gt;&lt;img alt="CRC protects the wire" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/SvccvofBHfI/AAAAAAAAAjY/PZrUCev60kU/s640/crcwire.png" style="border: 0px; padding: 3px;" title="Its 11 oclock, do you know where your data is?" width="404" height="175" /&gt;&lt;/center&gt;

&lt;p&gt;If you care about the data you send over the network, you should include your own integrity check at the application level. This is another good argument for using &lt;a href="http://en.wikipedia.org/wiki/Transport_Layer_Security"&gt;SSL&lt;/a&gt;: not only do you protect privacy by encrypting the data, you also get a strong end-to-end integrity check.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-4329324568218475678?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=If9qG37blRQ:Y6L3XG0E1b8:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=If9qG37blRQ:Y6L3XG0E1b8:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=If9qG37blRQ:Y6L3XG0E1b8:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=If9qG37blRQ:Y6L3XG0E1b8:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=If9qG37blRQ:Y6L3XG0E1b8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=If9qG37blRQ:Y6L3XG0E1b8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=If9qG37blRQ:Y6L3XG0E1b8:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=If9qG37blRQ:Y6L3XG0E1b8:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/If9qG37blRQ" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=4329324568218475678" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/4329324568218475678?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/4329324568218475678?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/11/ethernet-integrity-or-lack-thereof.html" title="Ethernet Integrity, or the Lack Thereof" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/Svb9kHe9fsI/AAAAAAAAAi4/FEMd6FcivjQ/s72-c/switch.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Ak8CQXg9cSp7ImA9WxNUF0o.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-2010510057957347739</id><published>2009-11-09T07:01:00.000-08:00</published><updated>2009-11-09T07:01:00.669-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-09T07:01:00.669-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Knight Rider GPS</title><content type="html">&lt;center&gt;&lt;img border="0" width="533" height="475" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsdgvRP6lAI/AAAAAAAAAdw/TE6JKBRVnxk/s640/KnightRiderGPS.jpg" style="border: 0px; padding: 3px 15px 3px 0px;" alt="Knight Rider GPS $149 at Frys"  title="Its a Frys ad, of course." /&gt;&lt;/center&gt;

&lt;p&gt;You mean my GPS unit can sound like the authentic voice of &lt;a href="http://en.wikipedia.org/wiki/KITT"&gt;K.I.T.T&lt;/a&gt;? Sign me up!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-2010510057957347739?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=fhXcmzIPfcU:KCsdYc6ekR0:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=fhXcmzIPfcU:KCsdYc6ekR0:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=fhXcmzIPfcU:KCsdYc6ekR0:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=fhXcmzIPfcU:KCsdYc6ekR0:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=fhXcmzIPfcU:KCsdYc6ekR0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=fhXcmzIPfcU:KCsdYc6ekR0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=fhXcmzIPfcU:KCsdYc6ekR0:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=fhXcmzIPfcU:KCsdYc6ekR0:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/fhXcmzIPfcU" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=2010510057957347739" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2010510057957347739?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2010510057957347739?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/11/knight-rider-gps.html" title="Knight Rider GPS" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SsdgvRP6lAI/AAAAAAAAAdw/TE6JKBRVnxk/s72-c/KnightRiderGPS.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEUNRH89eyp7ImA9WxNUEkg.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-3239294776308309092</id><published>2009-11-03T05:12:00.000-08:00</published><updated>2009-11-03T05:51:35.163-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-03T05:51:35.163-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="architecture" /><title>Delivering Apple TV Around the Planet</title><content type="html">&lt;p&gt;I am a long time Macintosh user, and though I don't generally write about Apple products I'm going to branch out a bit this time. These observations are rather obvious, but I'm going to do it anyway. Pppffftt.&lt;/p&gt;

&lt;img alt="iMac 27 inch" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/SuWxTnUMWtI/AAAAAAAAAhk/wcrORBxsnfk/s160/imac27.png" align=right style="border: 0px; padding: 3px;" title="Ooooh, shiny!" width="160" height="129" /&gt;
&lt;ol&gt;
&lt;li&gt;Apple is reportedly pitching a &lt;a href="http://mediamemo.allthingsd.com/20091102/apples-itunes-pitch-tv-for-30-a-month/"&gt;$30/month&lt;/a&gt; subscription for TV via iTunes to content producers, to be offered sometime in early 2010.&lt;/li&gt;
&lt;li&gt;According to the &lt;a href="http://www.ifixit.com/Teardown/iMac-Intel-27-Inch/1236/1"&gt;iFixit teardown&lt;/a&gt;, the LCD in the &lt;a href="http://www.appleinsider.com/articles/09/10/20/apple_unveils_new_imacs_with_21_5_and_27_inch_displays.html"&gt;recently announced&lt;/a&gt; 27" iMac is an In Plane Switching (IPS) &lt;a href="http://www.businessinsider.com/2009/1/lg-apple-displays"&gt;design by LG&lt;/a&gt;. This provides a very wide viewing angle compared to the Twisted Nematic (TN) LCDs typically used in personal computers. IPS LCDs are generally used in television sets, as one wants to see the TV from the entire width of the couch not just one narrow section.&lt;/li&gt;
&lt;li&gt;The iMac LCD has an unusual native resolution, 2560x1440. It is exactly double in each dimension as the &lt;a href="http://www.apple.com/appletv/"&gt;AppleTV&lt;/a&gt;, making it straightforward to optimize content for both devices.&lt;/li&gt;
&lt;li&gt;There is no TV tuner in either AppleTV or the iMac, though of course &lt;a href="http://www.elgato.com/"&gt;external USB tuners&lt;/a&gt; for broadcast HDTV are available.  Nonetheless, HDTV broadcast is yesterday's technology.&lt;/li&gt;
&lt;li&gt;Apple is spending $1 billion to &lt;a href="http://www.cultofmac.com/interview-apples-gigantic-new-data-center-hints-at-cloud-computing/14680"&gt;build&lt;/a&gt; a &lt;a href="http://www.wired.com/gadgetlab/2009/08/apple-cloud/"&gt;massive&lt;/a&gt; &lt;a href="http://arstechnica.com/apple/news/2009/08/experts-debate-apples-plans-for-huge-nc-data-center.ars"&gt;datacenter&lt;/a&gt; in Maiden, North Carolina. Certainly Apple's current &lt;a href="http://mac.com/"&gt;MobileMe&lt;/a&gt; and &lt;a href="http://www.itunes.com/"&gt;iTunes&lt;/a&gt; services demand significant capacity to host them, but with such a large investment it seems likely that Apple is looking to expand into new areas and not just continue its existing services.&lt;/li&gt;
&lt;li&gt;Altogether Apple is budgeting &lt;a href="http://digitaldaily.allthingsd.com/20091102/aapl-capex/"&gt;$1.9 billion for capital expenditures&lt;/a&gt; in fiscal 2010, an increase from the $1.1 billion in 2009.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img alt="AppleTV" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/SuWxfsJbP4I/AAAAAAAAAhs/I-qPHMFHTtc/s160/appletv.jpg" align=right style="border: 0px; padding: 3px;" title="Its so tiny!" width="71" height="76" /&gt;So, Apple is preparing to do to video distribution what it did in music, providing a complete solution including content, delivery, and customer device, right? Apple already provides selected video content on iTunes, and can expand from there.&lt;/p&gt;

&lt;p&gt;Though there are a lot of clues, there is a big piece missing. If one is looking to spend billions to develop the infrastructure to become a big player in video distribution, a single massive datacenter on the US east coast is not the way to do it. It leaves you beholden to others to carry the bits around the planet, which becomes the dominant cost of the business.&lt;/p&gt;

&lt;center&gt;&lt;img alt="Delivering Apple content" border="0" src="http://2.bp.blogspot.com/_WibILqsOlLg/SvAqmbpZ7-I/AAAAAAAAAiE/Cxh3v74KDqw/s640/appleisp.png"  style="border: 0px; padding: 3px;" title="...and a miracle happens." width="486" height="204" /&gt;&lt;/center&gt;

&lt;p&gt;The modern Internet consists of a series of interconnected backbone networks, generally referred to as &lt;a href="http://en.wikipedia.org/wiki/Autonomous_system_(Internet)"&gt;&amp;quot;Autonomous Systems&amp;quot;&lt;/a&gt; following the BGP terminology. Packets leave the datacenter and traverse the backbones on their way to their destination. The final telecom facility before the packet reaches its destination is called the &lt;a href="http://en.wikipedia.org/wiki/Point_of_presence"&gt;Edge Point of Presence&lt;/a&gt;. Delivering media streams all the way across the internet to thousands of individual subscribers incurs significant bandwidth costs. &lt;a href="http://en.wikipedia.org/wiki/Content_delivery_network"&gt;Content Delivery Networks&lt;/a&gt; reduce the bandwidth costs by scattering small caching servers across thousands of POPs, serving each subscriber from the closest cache.&lt;/p&gt;

&lt;p&gt;Apple currently relies on both &lt;a href="www.akamai.com/"&gt;Akamai&lt;/a&gt; and &lt;a href="www.limelightnetworks.com/"&gt;Limelight&lt;/a&gt; to deliver its iTunes content. Apple could certainly expand its current relationship with those vendors to carry substantially more video traffic... but for the kind of investment they are making, it seems like the money would be better spent scattering a number of smaller facilities across the planet. &lt;a href="http://www.joost.com"&gt;Peer to peer&lt;/a&gt; between end users seems like an ideal way to distribute video by offloading the bandwidth costs, but in practice it has &lt;a href="http://gigaom.com/2009/06/30/what-went-wrong-with-joost/"&gt;not worked&lt;/a&gt; &lt;a href="http://mashable.com/2009/07/01/joost-fail/"&gt;very well&lt;/a&gt;. Content distribution at scale is something which requires significant investment.&lt;/p&gt;

&lt;p&gt;Apple has &lt;a href="http://www.techcrunch.com/2009/10/20/apples-sauce-34-billion-in-cash-stock-peaks-and-mysterious-shipping-anomalies/"&gt;$34 billion&lt;/a&gt; in liquid assets, and an economic recession is a great time to buy. I'll be watching for indications that Apple is bringing this solution in house either by building lots of smaller facilities, perhaps with their own fiber network between them, or by building or acquiring a CDN of their own. Massive investment at the endpoints while remaining completely dependent on others for the connection between them doesn't make sense.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-3239294776308309092?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=qu0Y03K4SnY:Bd7TFXZ63kM:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=qu0Y03K4SnY:Bd7TFXZ63kM:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=qu0Y03K4SnY:Bd7TFXZ63kM:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=qu0Y03K4SnY:Bd7TFXZ63kM:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=qu0Y03K4SnY:Bd7TFXZ63kM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=qu0Y03K4SnY:Bd7TFXZ63kM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=qu0Y03K4SnY:Bd7TFXZ63kM:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=qu0Y03K4SnY:Bd7TFXZ63kM:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/qu0Y03K4SnY" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=3239294776308309092" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3239294776308309092?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3239294776308309092?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/11/delivering-apple-tv-around-planet.html" title="Delivering Apple TV Around the Planet" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/SuWxTnUMWtI/AAAAAAAAAhk/wcrORBxsnfk/s72-c/imac27.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUYCQ3o9fip7ImA9WxNUEUs.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-8171464967823955239</id><published>2009-11-02T05:01:00.000-08:00</published><updated>2009-11-02T05:06:02.466-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-02T05:06:02.466-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Lotus 123 for Macintosh</title><content type="html">&lt;center&gt;&lt;img border="0" width="266" height="341" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsdefSYW4yI/AAAAAAAAAdo/tJTy9d8XE70/s640/lotus123.jpg" style="border: 0px; padding: 3px 15px 3px 0px;" alt="User Manual for Lotus 123 for Macintosh"  title="Oh, Lotus 1-2-3, how I miss thy sweet, sweet embrace." /&gt;&lt;/center&gt;

&lt;p&gt;Which is more pathetic?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That I actually &lt;i&gt;purchased&lt;/i&gt; Lotus 1-2-3 for Macintosh in 1991?&lt;/li&gt;
&lt;li&gt;That 18 years later, I still have the manual?&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-8171464967823955239?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=tIkyq5N1E44:wA8SyyrNyWk:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=tIkyq5N1E44:wA8SyyrNyWk:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=tIkyq5N1E44:wA8SyyrNyWk:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=tIkyq5N1E44:wA8SyyrNyWk:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=tIkyq5N1E44:wA8SyyrNyWk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=tIkyq5N1E44:wA8SyyrNyWk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=tIkyq5N1E44:wA8SyyrNyWk:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=tIkyq5N1E44:wA8SyyrNyWk:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/tIkyq5N1E44" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=8171464967823955239" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8171464967823955239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8171464967823955239?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/11/lotus-123-for-macintosh.html" title="Lotus 123 for Macintosh" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SsdefSYW4yI/AAAAAAAAAdo/tJTy9d8XE70/s72-c/lotus123.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Ak8FQnc9fCp7ImA9WxNVGUk.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-2631300324107870983</id><published>2009-10-30T17:26:00.000-07:00</published><updated>2009-10-30T17:26:53.964-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-30T17:26:53.964-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Joke" /><title>Disallow:/tricks</title><content type="html">&lt;p&gt;This is cute, pointed out in a &lt;a href="http://twitter.com/mattcutts/status/5301611018"&gt;tweet&lt;/a&gt; by &lt;a href="http://mattcutts.com/blog/"&gt;Matt Cutts&lt;/a&gt;. There is a Halloween easter egg in &lt;a href="http://www.google.com/robots.txt"&gt;Google's robots.txt&lt;/a&gt; file.&lt;/p&gt;

&lt;pre style="margin: 2em 5em 2em 5em; padding: 1em; border-width: 1px; border-color: #999999; border-style: solid; background-color: #ccccdd; font-family: monospace; line-height: 1.4em;"&gt;
Disallow: /errors/
Disallow: /voice/fm/
Disallow: /voice/media/
Disallow: /voice/shared/
Disallow: /app/updates

&lt;span style="font-weight: bold;"&gt;User-agent: Kids
Disallow: /tricks
Allow: /treats&lt;/span&gt;

Sitemap: http://www.gstatic.com/s2/...
&lt;/pre&gt;

&lt;p&gt;Sadly neither &lt;a href="http://www.google.com/tricks/"&gt;/tricks&lt;/a&gt; nor &lt;a href="http://www.google.com/treats/"&gt;/treats&lt;/a&gt; actually exists.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-2631300324107870983?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cMHo_Fx5ugs:48q5ctdeVjA:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cMHo_Fx5ugs:48q5ctdeVjA:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cMHo_Fx5ugs:48q5ctdeVjA:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cMHo_Fx5ugs:48q5ctdeVjA:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cMHo_Fx5ugs:48q5ctdeVjA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cMHo_Fx5ugs:48q5ctdeVjA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cMHo_Fx5ugs:48q5ctdeVjA:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cMHo_Fx5ugs:48q5ctdeVjA:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/cMHo_Fx5ugs" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=2631300324107870983" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2631300324107870983?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2631300324107870983?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/disallowtricks.html" title="Disallow:/tricks" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEEAQH8-fip7ImA9WxNVFUg.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-7970094035264400116</id><published>2009-10-26T03:24:00.000-07:00</published><updated>2009-10-26T03:24:01.156-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-26T03:24:01.156-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Current GMail Ads</title><content type="html">&lt;p&gt;Here are the ads currently showing in my GMail:&lt;/p&gt;

&lt;center&gt;&lt;img alt="Insomnia Ads in GMail" border="0" height="152" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsdZepdBeUI/AAAAAAAAAdQ/CFyiCjwbbmY/s320/insomnia.png" style="border: 0px; padding: 3px 15px 3px 0px;" title="Ummmm, thanks." width="230" /&gt;&lt;/center&gt;

&lt;p&gt;I wonder what they are trying to tell me...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-7970094035264400116?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=1SW0BOSkfxo:pD5qrySsg_A:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=1SW0BOSkfxo:pD5qrySsg_A:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=1SW0BOSkfxo:pD5qrySsg_A:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=1SW0BOSkfxo:pD5qrySsg_A:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=1SW0BOSkfxo:pD5qrySsg_A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=1SW0BOSkfxo:pD5qrySsg_A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=1SW0BOSkfxo:pD5qrySsg_A:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=1SW0BOSkfxo:pD5qrySsg_A:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/1SW0BOSkfxo" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=7970094035264400116" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/7970094035264400116?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/7970094035264400116?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/current-gmail-ads.html" title="Current GMail Ads" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SsdZepdBeUI/AAAAAAAAAdQ/CFyiCjwbbmY/s72-c/insomnia.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0UBR3w-cSp7ImA9WxNVE08.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-6725217137893223416</id><published>2009-10-23T05:25:00.000-07:00</published><updated>2009-10-23T13:20:56.259-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-23T13:20:56.259-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>ARM Cortex A5</title><content type="html">&lt;p&gt;On October 21 &lt;a href="http://www.arm.com"&gt;ARM&lt;/a&gt; &lt;a href="http://www.arm.com/news/26196.html"&gt;announced&lt;/a&gt; a new CPU design at the low end of their range, the &lt;a href="http://www.arm.com/products/CPUs/ARM-Cortex-A5.html"&gt;Cortex A5&lt;/a&gt;. It is intended to replace the earlier &lt;a href="http://www.arm.com/products/CPUs/families/ARM7Family.html"&gt;ARM7&lt;/a&gt;, &lt;a href="http://www.arm.com/products/CPUs/families/ARM9EFamily.html"&gt;ARM9&lt;/a&gt;, and &lt;a href="http://www.arm.com/products/CPUs/families/ARM11Family.html"&gt;ARM11&lt;/a&gt; parts. The A5 can have up to 4 cores, but given its positioning as the smallest ARM the single core variant will likely dominate.&lt;/p&gt;

&lt;p&gt;To me the most interesting aspect of this announcement is that when the Cortex A5 ships (in 2011!) all ARM processors, regardless of price range, will have an MMU. The older &lt;a href="http://www.arm.com/products/CPUs/ARM7TDMI.html"&gt;ARM7TDMI&lt;/a&gt; relied on purely physical addressing, necessitating the use of either &lt;a href="http://www.uclinux.org/"&gt;uClinux&lt;/a&gt;, &lt;a href="http://www.windriver.com/products/vxworks/"&gt;vxWorks&lt;/a&gt;, or a similar RTOS. With the ARM Cortex processor family any application requiring a 32 bit CPU will have the standard Linux kernel as an option.&lt;/p&gt;

&lt;p&gt;&lt;span style="font-size: x-small; color: #999;"&gt;Story first noted at &lt;a href="http://arstechnica.com/gadgets/news/2009/10/arm-fills-out-cpu-lineup-with-cortex-a5.ars"&gt;Ars Technica&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;center&gt;&lt;img border="0" width="668" height="314" src="http://3.bp.blogspot.com/_WibILqsOlLg/SuGf5b1yh0I/AAAAAAAAAhU/TIo5GjZF-wA/s1600/cortex.jpg" style="border: 0px; margin: 3px;" alt="Cortex A5" /&gt;&lt;/center&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Update&lt;/span&gt;
&lt;p&gt;In the comments Dave Cason and Brooks Moses point out that I missed the ARM &lt;a href="http://www.arm.com/products/CPUs/embedded.html"&gt;Cortex-M&lt;/a&gt; range of processors, which are considerably smaller than the Cortex-A. The Cortex-Ms do not have a full MMU, though some parts in the range have a &lt;a href="http://www.arm.com/products/CPUs/ARM_Cortex-M3.html"&gt;memory protection unit&lt;/a&gt;. So it is &lt;i&gt;not&lt;/i&gt; the case that all ARM processors will now have MMUs. Mea culpa.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-6725217137893223416?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=ZG_a6d5_z74:QM6uRdypuTw:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=ZG_a6d5_z74:QM6uRdypuTw:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=ZG_a6d5_z74:QM6uRdypuTw:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=ZG_a6d5_z74:QM6uRdypuTw:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=ZG_a6d5_z74:QM6uRdypuTw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=ZG_a6d5_z74:QM6uRdypuTw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=ZG_a6d5_z74:QM6uRdypuTw:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=ZG_a6d5_z74:QM6uRdypuTw:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/ZG_a6d5_z74" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=6725217137893223416" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/6725217137893223416?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/6725217137893223416?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/arm-cortex-a5.html" title="ARM Cortex A5" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_WibILqsOlLg/SuGf5b1yh0I/AAAAAAAAAhU/TIo5GjZF-wA/s72-c/cortex.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UDSH85cCp7ImA9WxNWGUg.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-2723525760074226187</id><published>2009-10-19T05:18:00.000-07:00</published><updated>2009-10-19T05:27:59.128-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-19T05:27:59.128-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><category scheme="http://www.blogger.com/atom/ns#" term="Joke" /><title>Tweetravenous Solutions</title><content type="html">&lt;p&gt;Recently &lt;a href="http://regulargeek.com/"&gt;Rob Diana&lt;/a&gt; wrote a guest post at &lt;a href="http://workawesome.com/"&gt;WorkAwesome&lt;/a&gt;, &lt;a href="http://workawesome.com/office-life/balancing-work-and-social-media-addiction/"&gt;Balancing Work And Social Media Addiction&lt;/a&gt;. In it, he said:&lt;/p&gt;

&lt;div style="margin: 2em 8em 2em 8em; padding: 6px; border-width: 1px; border-color: #999999; border-style: solid; background-color: #eeeeee; font-style: italic;"&gt;&amp;quot;If your day job is sitting in a cube or corporate office somewhere, then you will need to limit your activity in some way. If you want to be like &lt;a href="http://scobleizer.com/"&gt;Robert Scoble&lt;/a&gt; or &lt;a href="http://www.louisgray.com/"&gt;Louis Gray&lt;/a&gt;, you will have to give up some sleep to stay active on several sites.&amp;quot;&lt;/div&gt;

&lt;p&gt;&lt;img style="padding:3px; border:0;" src="http://2.bp.blogspot.com/_WibILqsOlLg/StxWNA5f3pI/AAAAAAAAAfk/5PJCv8P-Kqk/s320/TwitterPatch.jpg" width="180" height="132" border="0" align=right alt="Twitter Skin Patch" title="Only apply one at a time. This is very, very important."&gt;
We at Tweetravenous Solutions have another solution to offer, which allows our customers to handle a full day's work, a full day of social media, and still get a full night's sleep! We call it the Social Media Patch. Our patented algorithms will monitor your social media feeds, collating and condensing updates from those you follow and encoding them in a complex matrix of proteins, amino acids, and caffeine. Its all infused into an easy-to-apply skin patch which can be worn inconspicuously beneath clothing. Even better, its in Real Time! &lt;span style="font-size: xx-small; color: #bbb;"&gt;(note1)&lt;/span&gt; &lt;/p&gt;

&lt;br clear=right/&gt;&amp;nbsp;&lt;br/&gt;
&lt;table rows=1 columns=3&gt;&lt;tr&gt;
&lt;td&gt;&lt;img style="padding:3px; border:0;" src="http://2.bp.blogspot.com/_WibILqsOlLg/StxWYaA9ErI/AAAAAAAAAfs/1nsNiQ7Yr20/s320/patches.jpg" width="250" height="177" border="0" align=left alt="Social Media Skin patches for twitter, friendfeed, and RSS." title="Facebook patch in development, we're discussing how to get around the terms &amp; conditions."&gt;&lt;/td&gt;

&lt;td width="10%"&gt;&amp;nbsp;&lt;/td&gt;

&lt;td&gt;
&lt;p&gt;&lt;blink&gt;&lt;b&gt;Never go without your twitter fix again!&lt;/b&gt;&lt;/blink&gt;&lt;/p&gt;

&lt;p&gt;&lt;blink&gt;&lt;b&gt;Feed your friendfeed need!&lt;/b&gt;&lt;/blink&gt;&lt;/p&gt;

&lt;p&gt;&lt;blink&gt;&lt;b&gt;Works with any RSS feed, too!&lt;/b&gt; &lt;span style="font-size: xx-small; color: #bbb;"&gt;(note2)&lt;/span&gt;&lt;/blink&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;br clear=left /&gt;&amp;nbsp;&lt;br/&gt;

&lt;table rows=1 columns=2&gt;&lt;tr&gt;
&lt;td&gt;Wait, there's more! For the &lt;i&gt;true&lt;/i&gt; Social Media Expert wanting to get an edge on the competition, we offer additional treatment options administered in our state-of-the-art facility!&lt;/td&gt;
&lt;td&gt;&lt;div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/toyohara/635710287/"&gt;&lt;a rel="cc:attributionURL" href="http://www.flickr.com/photos/toyohara/635710287/"&gt;&lt;img style="padding:7px; border:0;" src="http://2.bp.blogspot.com/_WibILqsOlLg/StxWhKcDQ_I/AAAAAAAAAf0/_lY63pk6B90/s320/TwitterIV.jpg" width="62" height="107" border="0" align=right alt="Twitter IV drip" title="The complete twitter hosebird stream, in an easy to digest form."&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Coming soon: two way communication! Thats right, you'll be able to retweet or reply using only the power of your mind! &lt;span style="color: #aaa;"&gt;(and bodily secretions)&lt;/span&gt; &lt;span style="font-size: xx-small; color: #bbb;"&gt;(note3)&lt;/span&gt;&lt;/p&gt;

&lt;br clear=right /&gt;&amp;nbsp;&lt;br/&gt;
&lt;p&gt;&lt;center&gt;&lt;div style="margin: 2em 8em 2em 8em; padding: 6px; border-width: 1px; border-color: #ff3333; border-style: solid; background-color: #ff1111; font-size: 130%; font-weight: bold;"&gt;&lt;blink&gt;Don't wait, call now!&lt;/blink&gt;&lt;/div&gt;&lt;/center&gt;&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br clear=right/&gt;
&lt;p&gt;&lt;span style="font-size: xx-small; color: #bbb;"&gt;note1: Real Time is defined as 48 hours, to allow for processing and express overnight delivery.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-size: xx-small; color: #bbb;"&gt;note2: pubsubhubbub and rssCloud support coming soon.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-size: xx-small; color: #bbb;"&gt;note3: Two way communication will incur additional cost, and add processing time. US Postal Service will not accept bodily secretions for delivery.&lt;/span&gt;&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;

&lt;p&gt;Author's note: I enjoyed Rob Diana's article, and recommend people to read it. When I saw &amp;quot;Social Media Addiction&amp;quot; in its title, the thought of a Nicotine patch came spontaneously to mind. It became a moral imperative to write this up.&lt;/p&gt;

&lt;p&gt;Also: sadly, modern browsers no longer render the &amp;lt;blink&amp;gt; tag. Too bad, it would have been sweet.&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-2723525760074226187?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=2B97vtk8Ogo:CvWC82G6fJQ:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=2B97vtk8Ogo:CvWC82G6fJQ:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=2B97vtk8Ogo:CvWC82G6fJQ:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=2B97vtk8Ogo:CvWC82G6fJQ:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=2B97vtk8Ogo:CvWC82G6fJQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=2B97vtk8Ogo:CvWC82G6fJQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=2B97vtk8Ogo:CvWC82G6fJQ:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=2B97vtk8Ogo:CvWC82G6fJQ:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/2B97vtk8Ogo" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=2723525760074226187" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2723525760074226187?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2723525760074226187?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/tweetravenous-solutions.html" title="Tweetravenous Solutions" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/StxWNA5f3pI/AAAAAAAAAfk/5PJCv8P-Kqk/s72-c/TwitterPatch.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0QCRHs_fCp7ImA9WxNWFU8.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-2076960992797864296</id><published>2009-10-14T06:01:00.000-07:00</published><updated>2009-10-14T06:02:45.544-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T06:02:45.544-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>AMD IOMMU: Missed Opportunity?</title><content type="html">&lt;p&gt;In 2007 AMD &lt;a href="http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/34434.pdf"&gt;implemented&lt;/a&gt; an &lt;a href="http://developer.amd.com/documentation/articles/pages/892006101.aspx"&gt;I/O MMU&lt;/a&gt; in their system architecture, which translates DMA addresses from peripheral devices to a different address on the system bus. There were several motivations for doing this:&lt;/p&gt;

&lt;ol&gt;
&lt;img border="0" width="367" height="253" src="http://4.bp.blogspot.com/_WibILqsOlLg/SsygRZysW0I/AAAAAAAAAeA/5u6iRsctQoI/s640/dvma.png" style="border: 0px; margin: 0px 0px 3px 3px;" align="right" alt="Direct Virtual Memory Access" title="Bounce buffers is a really cute name for a really nasty technique." /&gt;
&lt;li&gt;&lt;b&gt;Virtualization:&lt;/b&gt; DMA can be restricted to memory belonging to a single VM and to use the addresses from that VM, making it safe for a driver in that VM to take direct control of the device. This appears to be the largest motivation for adding the IOMMU.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;High Memory support:&lt;/b&gt; For I/O buses using 32 bit addressing, system memory above the 4GB mark is inaccessible. This has typically been handled using bounce buffers, where the hardware DMAs into low memory which the software will then &lt;i&gt;copy&lt;/i&gt; to its destination. An IOMMU allows devices to directly access any memory in the system, avoiding copies. There are a large number of PCI and PCI-X devices limited to 32 bit DMA addresses. Amazingly, a fair number of PCI Express devices are also limited to 32 bit addressing, probably because they repackage an older PCI design with a new interface.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Enable user space drivers&lt;/b&gt;: A user space application has no knowledge of physical addresses, making it impossible to program a DMA device directly. The I/O MMU can remap the DMA addresses to be the same as the user process, allowing direct control of the device. Only interrupts would still require kernel involvement.&lt;/li&gt;
&lt;/ol&gt;

&lt;br/&gt;&amp;nbsp;&lt;br clear=right /&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;I/O Device Latency&lt;/span&gt;
&lt;p&gt;&lt;img border="0" width="224" height="233" src="http://4.bp.blogspot.com/_WibILqsOlLg/Ssygb0Vw1QI/AAAAAAAAAeI/o392DshCMZ4/s320/latency.png" style="border: 0px; margin: 0px 3px 3px 0px;" align="left" alt="Multiple levels of bus bridging" title="I/O latency actually got worse recently, when memory controllers moved into the CPU." /&gt;
PCIe has a very high link bandwidth, making it easy to forget that its position in the system imposes several levels of bridging with correspondingly long latency to get to memory. The PCIe transaction first traverses the Northbridge and any internal switching or bus bridging it contains, on its way to the processor interconnect. The interconnect is HyperTransport for AMD CPUs, and QuickPath for Intel. Depending on the platform, the transaction might have to travel through multiple CPUs before it reaches its destination memory controller, where it can finally access its data. A PCIe Read transaction must then wend its way back through the same path to return the requested data.&lt;/p&gt;

&lt;img border="0" width="332" height="185" src="http://4.bp.blogspot.com/_WibILqsOlLg/SsygtAkrGyI/AAAAAAAAAeQ/dzd10BfXpm8/s640/graphics.png" style="border: 0px; margin: 0px 0px 3px 3px;" align="right" alt="Graphics device on CPU bus" title="This is Suns Creator graphics from the mid 1990s." /&gt;
&lt;p&gt;Much lower latency comes from sitting directly on the processor bus, and there have been systems where I/O devices &lt;a href="http://www.amd.com/us-en/Corporate/VirtualPressRoom/0,,51_104_543_15008~120740,00.html"&gt;sit&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Torrenza"&gt;directly&lt;/a&gt; &lt;a href="http://www.sun.com/desktop/products/graphics/upawhitepaper_jan99.pdf"&gt;beside&lt;/a&gt; CPUs. However CPU architectures rev that bus more often than it is practical to redesign a horde of peripherals. Attempts to place I/O devices on the CPU bus generally result in a requirement to maintain the &amp;quot;old&amp;quot; CPU bus as an I/O interface on the side of the next system chipset, to retain the expensive peripherals of the previous generation.&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br clear="all" /&gt;

&lt;span style="font-weight: bold; font-size: 115%;"&gt;The Missed Opportunity: DMA Read pipelining&lt;/span&gt;
&lt;p&gt;An IOMMU is not a new concept. &lt;a href="http://www.sun.com/products/microelectronics/products.jsp"&gt;Sun SPARC&lt;/a&gt;, some &lt;a href="http://en.wikipedia.org/wiki/Silicon_Graphics"&gt;SGI MIPS&lt;/a&gt; systems, and &lt;a href="http://www.intel.com/products/processor/itanium/"&gt;Intel's Itanium&lt;/a&gt; all employ them. Once you have taken the plunge to impose an address lookup between a DMA device and the rest of the system, there are other interesting things you can do in addition to remapping. For example, you can allow the mapping to specify additional attributes for the memory region. Knowing whether it is likely to do long, contiguous bursts or short concise updates allows optimizations to reduce latency by reading ahead, to transfer data faster by pipelining.&lt;/p&gt;

&lt;table style="border: 1px solid gray; padding: 2px; margin-top: 2em; margin-bottom: 2em;"&gt;
&lt;tr&gt;
&lt;td style="border: 1px solid gray; text-align: center; font-weight: bold; padding: 2px;"&gt;Without prefetch (CONSISTENT)&lt;/td&gt;
&lt;td style="border: 1px solid gray; text-align: center; font-weight: bold; padding: 2px;"&gt;With prefetch (STREAMING)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="border: 1px solid gray; text-align: center; padding: 5px;"&gt;&lt;img border="0" width="320" height="160" src="http://4.bp.blogspot.com/_WibILqsOlLg/Ssyg6zn3suI/AAAAAAAAAeY/DzoCvPuANy8/s320/consistread.gif" style="border: 0px; margin: 0px;" alt="DMA Read with no prefetch" title="In Solaris this is DDI_DMA_CONSISTENT. Ask me why I know this." /&gt;&lt;/td&gt;
&lt;td style="border: 1px solid gray; text-align: center; padding: 5px;"&gt;&lt;img border="0" width="320" height="160" src="http://4.bp.blogspot.com/_WibILqsOlLg/SsyhJfg8reI/AAAAAAAAAeg/NKO_JIUpp0I/s320/streamread.gif" style="border: 0px; margin: 0px;" alt="DMA Read with prefetch" title="In Solaris this is DDI_DMA_STREAMING. Ask me why I know this." /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;&lt;a href="http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/34434.pdf"&gt;AMD's IOMMU&lt;/a&gt; includes nothing like this. Presumably they wanted to confine the software changes to the Hypervisor alone, whilst choosing STREAMING versus CONSISTENT requires support in the driver of the device initiating DMA, but they could have ensured software compatibility by making CONSISTENT be the default with STREAMING only used by drivers which choose to implement it.&lt;/p&gt;


&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;What About Writes?&lt;/span&gt;
&lt;p&gt;The IOMMU in SPARC systems implemented additional support for DMA write operations. Writing less than a cache line is inefficient, as the I/O controller has to fetch the entire line from memory and merge the changes before writing it back. This was a problem for Sun, which had a largish number of existing &lt;a href="http://en.wikipedia.org/wiki/SBus"&gt;SBus&lt;/a&gt; devices issuing 16 or 32 byte writes while the SPARC cache line had grown to 64 bytes. A STREAMING mapping relaxed the requirement for instantaneous consistency: if a burst wrote the first part of a cache line, the I/O controller was allowed to buffer it in hopes that subsequent DMA operations would fill in the rest of the line. This is an idea whose time has come... and gone. The PCI spec takes great care to emphasize cache line sized writes using MWL or MWM, an emphasis which carries over the PCIe as well. There is little reason now to design coalescing hardware to optimize sub-cacheline writes.&lt;/p&gt;


&lt;table style="border: 1px solid gray; padding: 2px; margin-top: 2em; margin-bottom: 2em;"&gt;
&lt;tr&gt;
&lt;td style="border: 1px solid gray; text-align: center; font-weight: bold; padding: 2px;"&gt;Without buffering (CONSISTENT)&lt;/td&gt;
&lt;td style="border: 1px solid gray; text-align: center; font-weight: bold; padding: 2px;"&gt;With buffering (STREAMING)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="border: 1px solid gray; text-align: center; padding: 5px;"&gt;&lt;img border="0" width="320" height="160" src="http://4.bp.blogspot.com/_WibILqsOlLg/SsyhVdBnD-I/AAAAAAAAAeo/pl13ZiMLTDM/s320/consistwrite.gif" style="border: 0px; margin: 0px;" alt="DMA Write with no prefetch" title="In Solaris this is DDI_DMA_CONSISTENT. Ask me why I know this." /&gt;&lt;/td&gt;
&lt;td style="border: 1px solid gray; text-align: center; padding: 5px;"&gt;&lt;img border="0" width="320" height="160" src="http://4.bp.blogspot.com/_WibILqsOlLg/Ssyhg82KNgI/AAAAAAAAAew/Q384Sq4fQ4I/s320/streamwrite.gif" style="border: 0px; margin: 0px;" alt="DMA Write with prefetch" title="In Solaris this is DDI_DMA_STREAMING. Ask me why I know this." /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Closing Disclaimer&lt;/span&gt;
&lt;p&gt;Maybe I'm way off base in lamenting the lack of DMA read pipelining. Maybe all relevant PCIe devices always issue Memory Read Multiple requests for huge chunks of data, and the chipset already pipelines data fetch during such large transactions. Maybe. I doubt it, but maybe...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-2076960992797864296?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=4f1M1yYZXQs:rGjyq-Y-WMg:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=4f1M1yYZXQs:rGjyq-Y-WMg:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=4f1M1yYZXQs:rGjyq-Y-WMg:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=4f1M1yYZXQs:rGjyq-Y-WMg:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=4f1M1yYZXQs:rGjyq-Y-WMg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=4f1M1yYZXQs:rGjyq-Y-WMg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=4f1M1yYZXQs:rGjyq-Y-WMg:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=4f1M1yYZXQs:rGjyq-Y-WMg:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/4f1M1yYZXQs" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=2076960992797864296" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2076960992797864296?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/2076960992797864296?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/amd-iommu-missed-opportunity.html" title="AMD IOMMU: Missed Opportunity?" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_WibILqsOlLg/SsygRZysW0I/AAAAAAAAAeA/5u6iRsctQoI/s72-c/dvma.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UCQXs4eip7ImA9WxNWFE4.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-4711250258780634990</id><published>2009-10-13T05:01:00.000-07:00</published><updated>2009-10-13T05:01:00.532-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T05:01:00.532-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>WinXP Network Diagnostic</title><content type="html">&lt;center&gt;&lt;img border="0" width="540" height="275" src="http://2.bp.blogspot.com/_WibILqsOlLg/SsdbzAvIuyI/AAAAAAAAAdY/-7nIsg0rwkg/s640/winxpdiagsmall.png" style="border: 0px; padding: 3px 15px 3px 0px;" alt="Please contact your network administrator or helpdesk"  title="Great sleuthing, WindowsXP!" /&gt;&lt;/center&gt;

&lt;p&gt;Thanks, but I could probably have figured that out without help from the diagnostic utility.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-4711250258780634990?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=T_nVD0fnpv8:Tzo1MV7nano:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=T_nVD0fnpv8:Tzo1MV7nano:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=T_nVD0fnpv8:Tzo1MV7nano:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=T_nVD0fnpv8:Tzo1MV7nano:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=T_nVD0fnpv8:Tzo1MV7nano:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=T_nVD0fnpv8:Tzo1MV7nano:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=T_nVD0fnpv8:Tzo1MV7nano:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=T_nVD0fnpv8:Tzo1MV7nano:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/T_nVD0fnpv8" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=4711250258780634990" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/4711250258780634990?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/4711250258780634990?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/winxp-network-diagnostic.html" title="WinXP Network Diagnostic" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/SsdbzAvIuyI/AAAAAAAAAdY/-7nIsg0rwkg/s72-c/winxpdiagsmall.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0MMQn0ycSp7ImA9WxNWFUw.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-5031503359310416685</id><published>2009-10-11T03:59:00.000-07:00</published><updated>2009-10-14T04:24:43.399-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T04:24:43.399-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Product Development" /><title>A Cloud Over the Industry</title><content type="html">&lt;p&gt;&lt;a href="http://www.techcrunch.com/2009/10/10/t-mobile-sidekick-disaster-microsofts-servers-crashed-and-they-dont-have-a-backup/"&gt;Unbelievable:&lt;/a&gt;&lt;/p&gt;

&lt;p style="margin-left: 5em; margin-right: 10%; padding: 10px; background-color: #eeeeee;"&gt;Regrettably, based on &lt;a href="http://www.danger.com/"&gt;Microsoft/Danger's&lt;/a&gt; latest recovery assessment of their systems, we must now inform you that personal information stored on your device - such as contacts, calendar entries, to-do lists or photos - that is no longer on your Sidekick &lt;b&gt;almost certainly has been lost&lt;/b&gt; as a result of a server failure at Microsoft/Danger. That said, our teams continue to work around-the-clock in hopes of discovering some way to recover this information. However, the likelihood of a successful outcome is extremely low.&lt;/p&gt;

&lt;p style="margin-top:5px;"&gt;This kind of monumental failure casts a cloud over the entire industry (pun intended). How did it happen? I do not believe Danger could have operated without sufficient redundancy and without backups for so many years, it simply does not pass the smell test. There must be more to the story.&lt;/p&gt;

&lt;p&gt;On possible theory for unrecoverable loss of all customer data is actually &lt;i&gt;sabotage&lt;/i&gt; by a disgruntled insider. This is, itself, pretty unbelievable. Nonetheless according to &lt;a href="http://gigaom.com/2008/02/12/how-much-did-microsoft-pay-for-danger-find-out-here/"&gt;GigaOM&lt;/a&gt;, when Microsoft acquired Danger &amp;quot;...while some of the early investors got modest returns, I am told that the later-stage investors made out like bandits.&amp;quot; I wonder if the early employees also made only a modest payout in return for their years of effort, and had to watch the late stage investors take everything. Danger filed for IPO in late 2007, but was suddenly acquired by Microsoft in early 2008. What if the investors determined they would not make as much money in a large IPO as they would in a carefully arranged, smaller acquisition by Microsoft? For example, the term sheet might have included a substantial &lt;a href="http://www.feld.com/wp/archives/2005/01/term-sheet-liquidation-preference.html"&gt;liquidation preference&lt;/a&gt; but specify that all shares revert to common if the exit is above N dollars. For the investors, the best exit is (N-1) dollars; they maximize their return by keeping a larger fraction of a smaller pie. If they had &lt;a href="http://www.investopedia.com/terms/d/dragalongrights.asp"&gt;drag along&lt;/a&gt; rights, they could force the acquisition over the objections of employees and management. If the long-time employees watched their payday be snatched away... a workforce of disgruntled employees seems quite plausible.&lt;/p&gt;

&lt;p&gt;This is all, of course, complete speculation on my part. I simply cannot believe that the company could accidentally lose all data, for all customers, irrevocably. It doesn't make sense.&lt;/p&gt;

&lt;center&gt;&lt;img border="0" width="327" height="245" src="http://3.bp.blogspot.com/_WibILqsOlLg/StFgPWS2YSI/AAAAAAAAAe4/WbZKHAGND6c/s320/sidekick.jpg" style="border: 0px; padding: 3px 15px 3px 0px;" alt="Danger Sidekick"  title="Now in multiple color palettes." /&gt;&lt;/center&gt;

&lt;p&gt;Other links relating to this story:&lt;/p&gt;
&lt;ul type=none&gt;
&lt;li&gt;&lt;a href="http://gigaom.com/2009/10/10/when-cloud-fails-t-mobile-microsoft-lose-sidekick-customer-data/"&gt;GigaOM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.techcrunch.com/2009/10/10/t-mobile-sidekick-disaster-microsofts-servers-crashed-and-they-dont-have-a-backup/"&gt;TechCrunch&lt;/a&gt; (and a related &lt;a href="http://www.techcrunch.com/2009/10/10/respectfully-letting-data-die-a-natural-death/"&gt;followup&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.engadget.com/2009/10/10/t-mobile-we-probably-lost-all-your-sidekick-data/"&gt;Engadget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://epeus.blogspot.com/2009/10/t-mobile-contacts-roach-motel-loses.html"&gt;Kevin Marks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.appleinsider.com/articles/09/10/12/microsofts_sidekick_pink_problems_blamed_on_dogfooding_and_sabotage.html"&gt;AppleInsider&lt;/a&gt; (also pursues the sabotage angle)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-5031503359310416685?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=Qk1sWJ0kz8g:hGb1kgDfztk:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=Qk1sWJ0kz8g:hGb1kgDfztk:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=Qk1sWJ0kz8g:hGb1kgDfztk:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=Qk1sWJ0kz8g:hGb1kgDfztk:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=Qk1sWJ0kz8g:hGb1kgDfztk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=Qk1sWJ0kz8g:hGb1kgDfztk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=Qk1sWJ0kz8g:hGb1kgDfztk:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=Qk1sWJ0kz8g:hGb1kgDfztk:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/Qk1sWJ0kz8g" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=5031503359310416685" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/5031503359310416685?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/5031503359310416685?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/cloud-over-industry.html" title="A Cloud Over the Industry" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_WibILqsOlLg/StFgPWS2YSI/AAAAAAAAAe4/WbZKHAGND6c/s72-c/sidekick.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEcHSX49eyp7ImA9WxNWEEk.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-8850700983739748545</id><published>2009-10-08T05:01:00.000-07:00</published><updated>2009-10-08T15:47:18.063-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-08T15:47:18.063-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C Programming" /><title>Code Snippet: SO_BINDTODEVICE</title><content type="html">&lt;p&gt;In a system with multiple network interfaces, can you constrain a packet to go out one specific interface? If you answered &amp;quot;bind() the socket to an address,&amp;quot; you should read on.&lt;/p&gt;

&lt;p&gt;Why might one need to strictly control where packets can be routed? The best use case I know is when ethernet is used as a &lt;a href="http://codingrelic.geekhold.com/2008/07/control-plane-is-not-aircraft.html"&gt;control plane&lt;/a&gt; inside a product. Packets intended to go to another card within the chassis must not, under any circumstances, leave the chassis. You don't want  bugs or misconfiguration to result in leaking control traffic.&lt;/p&gt;

&lt;p&gt;The bind() system call is frequently misunderstood. It is used to bind to a particular IP address. Only packets destined to that IP address will be received, and any transmitted packets will carry that IP address as their source. bind() does not control anything about the routing of transmitted packets. So for example, if you bound to the IP address of eth0 but you send a packet to a destination where the kernel's best route goes out eth1, it will happily send the packet out eth1 with the source IP address of eth0. This is perfectly valid for TCP/IP, where packets can traverse unrelated networks on their way to the destination.&lt;/p&gt;

&lt;p&gt;In Linux, to control the physical topology of communication you use the SO_BINDTODEVICE socket option.&lt;/p&gt;

&lt;pre style="font-family: monospace; font-size: x-small; line-height: 1.1em; margin-left: 5em;"&gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;net/if.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;

int main(int argc, char **argv)
{
    int s;
    struct ifreq ifr;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) &amp;lt; 0) {
        &lt;i&gt;... error handling ...&lt;/i&gt;
    }

    memset(&amp;amp;ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
                (void *)&amp;amp;ifr, sizeof(ifr)) &amp;lt; 0) {
        &lt;i&gt;... error handling ...&lt;/i&gt;
    }
&lt;/pre&gt;

&lt;p&gt;SO_BINDTODEVICE forces packets on the socket to only egress the bound interface, regardless of what the IP routing table would normally choose. Similarly only packets which ingress the bound interface will be received on the socket, packets from other interfaces will not be delivered to the socket.&lt;/p&gt;

&lt;p&gt;There is no particular interaction between bind() and SO_BINDTODEVICE. It is certainly possible to bind to the IP address of the interface to which one will also SO_BINDTODEVICE, as this will ensure that the packets carry the desired source IP address. It is also permissible, albeit weird, to bind to the IP address of one interface but SO_BINDTODEVICE a different interface. It is unlikely that any ingress packets will carry the proper combination of destination IP address and ingress interface, but for very special use cases it could be done.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-8850700983739748545?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L6fvrB9nLNg:tSzMZ2Jpi-g:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L6fvrB9nLNg:tSzMZ2Jpi-g:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L6fvrB9nLNg:tSzMZ2Jpi-g:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L6fvrB9nLNg:tSzMZ2Jpi-g:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L6fvrB9nLNg:tSzMZ2Jpi-g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L6fvrB9nLNg:tSzMZ2Jpi-g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L6fvrB9nLNg:tSzMZ2Jpi-g:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L6fvrB9nLNg:tSzMZ2Jpi-g:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/L6fvrB9nLNg" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=8850700983739748545" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8850700983739748545?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8850700983739748545?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html" title="Code Snippet: SO_BINDTODEVICE" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkcCQXk-fSp7ImA9WxNXF0k.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-1436982634800718552</id><published>2009-10-05T05:01:00.000-07:00</published><updated>2009-10-05T05:01:00.755-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-05T05:01:00.755-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Captcha Text Wrong?</title><content type="html">&lt;br/&gt;
&lt;center&gt;&lt;img style="padding:3px 15px 3px 0px; border:0px;" src="http://2.bp.blogspot.com/_WibILqsOlLg/SsdWALcA2SI/AAAAAAAAAdI/qSPGkEY6f0c/s640/captcha.png" width="640" height="198" border="0" alt="Captcha Not Available" title="I typed it exactly, even the capitalization."&gt;&lt;/center&gt;

&lt;br/&gt;

&lt;p&gt;I typed it exactly, even the capitalization.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-1436982634800718552?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=WjzRz7IbEwU:88hCnq0u8k0:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=WjzRz7IbEwU:88hCnq0u8k0:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=WjzRz7IbEwU:88hCnq0u8k0:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=WjzRz7IbEwU:88hCnq0u8k0:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=WjzRz7IbEwU:88hCnq0u8k0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=WjzRz7IbEwU:88hCnq0u8k0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=WjzRz7IbEwU:88hCnq0u8k0:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=WjzRz7IbEwU:88hCnq0u8k0:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/WjzRz7IbEwU" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=1436982634800718552" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/1436982634800718552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/1436982634800718552?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/captcha-text-wrong.html" title="Captcha Text Wrong?" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/SsdWALcA2SI/AAAAAAAAAdI/qSPGkEY6f0c/s72-c/captcha.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUMCQXYyfip7ImA9WxNXFE0.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-8229431903357669644</id><published>2009-10-01T07:31:00.000-07:00</published><updated>2009-10-01T07:31:00.896-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T07:31:00.896-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>Yield to Your Multicore Overlords</title><content type="html">&lt;p&gt;ASIC design is all about juggling multiple competing requirements. You want to make the chip competitive by increasing its capabilities, by reducing its price, or both. Today we'll focus on the second half of that tradeoff, reducing the price.&lt;/p&gt;

&lt;p&gt;Chip fabrication is a statistical game: of the parts coming off the fab, some percentage simply do not work. The vendor runs test vectors against the chips, and throws away the ones which fail. This is called the yield, and is the primary factor determining the cost of the chip. If the yield is bad, so you have to fab a whole bunch of chips to get one that actually works, you have to charge more for that one working chip.&lt;/p&gt;

&lt;p&gt;To illustrate why most chips coming out of the fab do not work, I'd like to walk through part of manufacturing a chip. This information is from 1995 or so, when I was last seriously involved in a chip design, and describes a 0.8 micron process. So it is completely old and busted, but is sufficient for our purposes here.&lt;/p&gt;

&lt;div style="margin: 0em 5em 0em 5em; padding: 1em 2em 1em 2em; border: 1px solid black; background-color: #dddddd; font-size: x-small;"&gt;
&lt;p&gt;Begin by placing the silicon wafer in a nitrogen atmosphere. You deposit a photo-resist on the wafer, basically a goo which hardens when exposed to ultraviolet light. You place a shadow mask in front of a light source; the regions exposed to light will harden while those under the shadow mask remain soft. You then chemically etch off the soft regions of the photo-resist, leaving exposed silicon where they were. The hardened regions of photo-resist stay put.&lt;/p&gt;

&lt;p&gt;Next you heat the wafer to 400 degrees and pipe phosphorous into the nitrogen atmosphere. As the K atoms heat they begin moving faster and bouncing off the walls of the chamber. Some of them move fast enough that when they strike the surface of the wafer they break the Si crystal lattice and embed themselves in the silicon. If they strike the hardened photo-resist, they embed themselves in the resist; very, very few are moving fast enough to crash all the way through the photoresist into the silicon underneath.&lt;/p&gt;

&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsS73o1sarI/AAAAAAAAAcw/fsPLy-r8gb0/s320/electronmicroscope.png" width="88" height="96" align=right border="0" alt="Electron Microscopy image of a silicon die" title="Chip designers have been known to spell out their names or rude words in the top layer of metal."&gt;

&lt;p&gt;Next you use a different chemical process to strip off the hardened photoresist. You are left with a wafer which has phosphorous embedded in the places you wanted. Now you heat the wafer even higher, hot enough that the silicon atoms can move around more freely; they move back into position and reform the crystal lattice, burying the phosphorous atoms embedded within. This is called annealing. Now you have the p+ regions of the transistors.&lt;/p&gt;

&lt;p&gt;You repeat this process with aluminum ions to get the n- regions. Now you have transistors. Next you connect the transistors together with traces of aluminum (which I won't go into here). You cut the wafer to separate the die, and place each die in a package. You connect bonding wires from the edge of the die to the pins of the chip. And voila, you're done.&lt;/p&gt;
&lt;/div&gt;

&lt;br/&gt;

&lt;p&gt;It should be apparent that this is a probabalistic process. Sometimes, based purely on random chance, not enough phosphorous atoms embed themselves into the silicon and your transistors don't turn on. Sometimes too much phosphorous embeds and your transistors won't turn off. Sometimes the Si lattice is too badly damaged and the annealing is ineffective. Sometimes the metal doesn't line up with the vias. Sometimes a dust particle lands on the chip and you deposit metal on top of the dust mote. Sometimes the bonding doesn't line up with the pads. Etc etc.&lt;/p&gt;

&lt;p&gt;This is why the larger a chip grows, the more expensive it becomes. Its not because raw silicon wafers are particularly costly, its that the probability of there being a defect somewhere grows ever greater as the die becomes larger. The bigger the chip, the lower the yield of functional parts.&lt;/p&gt;

&lt;p&gt;&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsS8JEM0kcI/AAAAAAAAAc4/HQFbDKt3lMs/s320/NehalemSRAM.png" width="128" height="88" align=right border="0" alt="Intel Nehalem chip with SRAM highlited" title="Recursive redundancy: I used this image in an earlier blog post."&gt;
For at least 15 years that I know of, chip designs have improved their yield using redundancy. The earliest such efforts were done in on-chip memory: if your chip is supposed to include N banks of SRAM, put N+1 banks on the die connected with wires in the top most layer which can be cut using a laser. The SRAM occupies a large percentage of the total chip area, statistically it is likely that defects will be within the SRAM. You can then cut out the defective bank, and turn a defective chip into one that can be used. More recent silicon processes use fuses blown by the test fixture instead of lasers.&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Massively Multicore Processors&lt;/span&gt;

&lt;p&gt;Yesterday &lt;a href="http://www.nvidia.com/"&gt;NVidia&lt;/a&gt; &lt;a href="http://www.nvidia.com/object/io_1254288141829.html"&gt;announced&lt;/a&gt; &lt;a href="http://www.nvidia.com/object/fermi_architecture.html"&gt;Fermi&lt;/a&gt;, a beast of a chip with 512 Cuda GPU cores. They are arranged in 16 blocks of 32 cores each. At this kind of scale, I suspect it makes sense to include extra cores in the design to improve the yield. For example, perhaps each block actually has 33 cores in the silicon so that a defective core can be tolerated.&lt;/p&gt;

&lt;p&gt;In order to avoid having weird performance variations in the product, the extra resources are generally inaccessible if not used for yield improvement. That is even though the chip might have 528 cores physically present, no more than 512 could ever be used.&lt;/p&gt;

&lt;center&gt;&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsS8aev-2MI/AAAAAAAAAdA/6zxrWiTP3UA/s640/fermi.png" width="417" height="326"  border="0" alt="NVidia Fermi GPU" title="It looks like some kind of weird backgammon board."&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-8229431903357669644?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=mJ7pMw7heX0:w9bLoz6fVmo:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=mJ7pMw7heX0:w9bLoz6fVmo:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=mJ7pMw7heX0:w9bLoz6fVmo:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=mJ7pMw7heX0:w9bLoz6fVmo:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=mJ7pMw7heX0:w9bLoz6fVmo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=mJ7pMw7heX0:w9bLoz6fVmo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=mJ7pMw7heX0:w9bLoz6fVmo:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=mJ7pMw7heX0:w9bLoz6fVmo:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/mJ7pMw7heX0" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=8229431903357669644" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8229431903357669644?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8229431903357669644?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/10/yield-to-your-multicore-overlords.html" title="Yield to Your Multicore Overlords" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SsS73o1sarI/AAAAAAAAAcw/fsPLy-r8gb0/s72-c/electronmicroscope.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEUESHszeCp7ImA9WxNXFUU.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-8872435165715583910</id><published>2009-09-28T06:06:00.000-07:00</published><updated>2009-10-03T08:03:29.580-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-03T08:03:29.580-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="embedded" /><title>49.710269618056 Days</title><content type="html">&lt;p&gt;&lt;a href="http://www.wdc.com/"&gt;Western Digital&lt;/a&gt; recently corrected a firmware issue in certain models of VelociRaptor where the drive would erroneously report an error to the host after &lt;a href="http://www.theregister.co.uk/2009/09/28/velociraptor_49day_bug/"&gt;49 days of operation&lt;/a&gt;. Somewhat inconveniently for RAID arrays, if all drives powered on at the same time they would all report an error at the same time.&lt;/p&gt;

&lt;p&gt;Informed speculation: the drive reports an error after exactly 49 days, 17 hours, 2 minutes, 47 seconds, and 294.999 milliseconds of operation. That is the moment where a millisecond timer overflows an unsigned 32 bit integer.&lt;/p&gt;

&lt;center&gt;&lt;img style="padding:20px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SsC0WqP0m_I/AAAAAAAAAcQ/WT2ZFfSR94Q/s320/VelociRaptor.jpg" width="400" height="371" border="0" alt="WD VelociRaptor" title="I suspect the retail version comes with a cover."&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-8872435165715583910?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=XNgbr6sk-Qc:BpPx6-GsPOA:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=XNgbr6sk-Qc:BpPx6-GsPOA:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=XNgbr6sk-Qc:BpPx6-GsPOA:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=XNgbr6sk-Qc:BpPx6-GsPOA:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=XNgbr6sk-Qc:BpPx6-GsPOA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=XNgbr6sk-Qc:BpPx6-GsPOA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=XNgbr6sk-Qc:BpPx6-GsPOA:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=XNgbr6sk-Qc:BpPx6-GsPOA:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/XNgbr6sk-Qc" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=8872435165715583910" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8872435165715583910?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8872435165715583910?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/49710269618056-days.html" title="49.710269618056 Days" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SsC0WqP0m_I/AAAAAAAAAcQ/WT2ZFfSR94Q/s72-c/VelociRaptor.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CU4NQn84fCp7ImA9WxNQFk8.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-3897899408953012953</id><published>2009-09-22T05:53:00.000-07:00</published><updated>2009-09-22T05:53:13.134-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T05:53:13.134-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>A Pudgier Tux</title><content type="html">&lt;p&gt;&lt;a href="http://lewing.org/"&gt;&lt;img style="padding:3px 15px 3px 0px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SrjH7KvKsbI/AAAAAAAAAcA/SVknmKMLZEk/s320/tux.png" width="132" height="171" align=right border="0" alt="Tux the Penguin" title="Original image by Larry Ewing (lewing@isc.tamu.edu), created using The GIMP. File downloadded from Wikipedia."&gt;&lt;/a&gt;
At LinuxCon 2009 a discussion arose about the Linux kernel becoming gradually slower with each new release. &amp;quot;Yes, it's a problem,&amp;quot; &lt;a href="http://www.theregister.co.uk/2009/09/22/linus_torvalds_linux_bloated_huge/"&gt;said Linus Torvalds&lt;/a&gt;. &amp;quot;The kernel is huge and bloated, and our icache footprint is scary. I mean, there is no question about that. And whenever we add a new feature, it only gets worse.&amp;quot;&lt;/p&gt;

&lt;p&gt;I think the addition of new features is a red herring, and the real problem is  in letting Tux &lt;i&gt;eat&lt;/i&gt; the herring. Just hide the jars, maybe get a treadmill, and everything will go back to the way it was.&lt;/p&gt;

&lt;center&gt;&lt;div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/oleswerdlow/3107131919/"&gt;&lt;a rel="cc:attributionURL" href="http://www.flickr.com/photos/oleswerdlow/"&gt;&lt;img style="padding:3px 15px 3px 0px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SrjIGz4eQ-I/AAAAAAAAAcI/iRZy7petBaI/s640/herring.jpg" width="278" height="377" border="0" alt="Pickled Herring" title="Original image by oleswerdlow on flikr, licensed under Creative Commons"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/center&gt;

&lt;br/&gt;

&lt;p&gt;&lt;div style="font-size: x-small;"&gt;Story originally noted in &lt;a href="http://www.theregister.co.uk/2009/09/22/linus_torvalds_linux_bloated_huge/"&gt;The Register&lt;/a&gt;.&lt;/div&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-3897899408953012953?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L-H6dPRsdMY:p3pZqwSzqGQ:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L-H6dPRsdMY:p3pZqwSzqGQ:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L-H6dPRsdMY:p3pZqwSzqGQ:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L-H6dPRsdMY:p3pZqwSzqGQ:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L-H6dPRsdMY:p3pZqwSzqGQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L-H6dPRsdMY:p3pZqwSzqGQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=L-H6dPRsdMY:p3pZqwSzqGQ:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=L-H6dPRsdMY:p3pZqwSzqGQ:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/L-H6dPRsdMY" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=3897899408953012953" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3897899408953012953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3897899408953012953?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/pudgier-tux.html" title="A Pudgier Tux" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SrjH7KvKsbI/AAAAAAAAAcA/SVknmKMLZEk/s72-c/tux.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkMDSHg7eip7ImA9WxNQEUQ.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-6642491959571034153</id><published>2009-09-17T05:01:00.000-07:00</published><updated>2009-09-17T05:27:59.602-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T05:27:59.602-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="embedded" /><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>Jasper Forest x86</title><content type="html">&lt;p&gt;&lt;a href="http://www.intel.com/embedded/"&gt;Intel&lt;/a&gt; has a long but uneven history in the embedded market. In the early days of the personal computer Intel released the 80286 as a followon to the original 8086. There actually &lt;i&gt;was&lt;/i&gt; an 80186: it was a &lt;a href="http://en.wikipedia.org/wiki/Intel_80186"&gt;more integrated&lt;/a&gt; version of the 8086 aimed at embedded applications. Intel's interest in embedded markets has waxed and waned over the years, but it is an area where Intel still has room for significant growth.&lt;/p&gt;

&lt;p&gt;I wrote about &lt;a href="http://codingrelic.geekhold.com/2008/03/embedded-processors.html"&gt;x86 for embedded use&lt;/a&gt; about a year and a half ago, with four main points:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;b&gt;Volume Discounts&lt;/b&gt;&lt;br/&gt;PC pricing thresholds at 50,000 units have to be rethought for a less homogenous market&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;System on Chip (SoC)&lt;/b&gt;&lt;br/&gt;Board space is at a premium, we need fewer components in the system&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Production lifetime&lt;/b&gt;&lt;br/&gt;These systems are not redesigned every few months, chips have to remain in production longer&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Power and heat&lt;/b&gt;&lt;br/&gt;Airflow is more constrained, and the system has other heat generating components besides the CPU complex&lt;/li&gt;
&lt;/ul&gt;

&lt;img style="padding:3px 15px 3px 0px; border:0px;" src="http://4.bp.blogspot.com/_WibILqsOlLg/SrF06hjqvbI/AAAAAAAAAb4/awBgUEbesM0/s800/JasperForestVsNehalem.jpg" width="393" height="512" align=left border="0" alt="Nehalem vs Jasper Forest" title="Oooh, shiny!"&gt;

&lt;p&gt;At the &lt;a href="http://www.intel.com/IDF/"&gt;Intel Developer Forum&lt;/a&gt; next week Intel is expected to focus on embedded applications for its products. In advance of IDF Intel announced the &lt;a href="http://www.intel.com/pressroom/kits/events\idffall_2009\index.htm"&gt;Jasper Forest&lt;/a&gt; CPU, a System on Chip version of Nehalem. It is based on a 1, 2, or 4 core CPU plus an integrated PCI-e controller, so it does not need a separate northbridge chip. Intel also committed to a 7 year production lifetime, allowing the part to be designed into products which will remain on the market for a while. I'd speculate that Intel will offer industrial temperature grade parts as well, perhaps at lower frequencies.&lt;/p&gt;

&lt;p&gt;
&lt;p&gt;Jasper Forest is particularly suited for and aimed at storage applications. It has additional hardware for RAID support (presumably XOR &amp; ECC generation), and a feature to use main memory as a nonvolatile buffer cache. When loss of power is detected the chip will flush any pending writes out to RAM and then set the DRAM to self-refresh before shutting down. By including a battery sufficient to power the DRAM, the system can avoid the need for a separate nonvolatile data buffer like SRAM.&lt;/p&gt;

&lt;p&gt;This is a good approach for Intel: target silicon at specific high margin, growing application areas. Go for markets with moderate power consumption requirements, as x86 is clearly not ready for small battery powered applications like phones.  &lt;a href="http://arstechnica.com/hardware/news/2009/09/intel-to-launch-smartphone-embedded-offenive-next-week.ars"&gt;Ars Technica discusses&lt;/a&gt; Intel's upcoming weapon for getting into mobile and other battery powered markets, a version of their 32nm process which reduces leakage current to almost nothing. An idle x86 would consume essentially no power, which would be huge.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-6642491959571034153?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=6Jyw0GvN6ac:1F22p1iO2hY:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=6Jyw0GvN6ac:1F22p1iO2hY:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=6Jyw0GvN6ac:1F22p1iO2hY:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=6Jyw0GvN6ac:1F22p1iO2hY:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=6Jyw0GvN6ac:1F22p1iO2hY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=6Jyw0GvN6ac:1F22p1iO2hY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=6Jyw0GvN6ac:1F22p1iO2hY:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=6Jyw0GvN6ac:1F22p1iO2hY:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/6Jyw0GvN6ac" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=6642491959571034153" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/6642491959571034153?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/6642491959571034153?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/jasper-forest-x86.html" title="Jasper Forest x86" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_WibILqsOlLg/SrF06hjqvbI/AAAAAAAAAb4/awBgUEbesM0/s72-c/JasperForestVsNehalem.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Dk4ASXczeyp7ImA9WxNQEEw.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-427871956314027663</id><published>2009-09-15T04:42:00.000-07:00</published><updated>2009-09-15T04:42:28.983-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-15T04:42:28.983-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>Soft Errors Are Hard Problems</title><content type="html">&lt;p&gt;&amp;quot;Soft Error&amp;quot; is a euphemism in the semiconductor industry for &amp;quot;the silicon did the wrong thing.&amp;quot; Soft errors can occur when a circuit is infused with a sudden burst of energy from an external source, for example when it is hit by a high energy subatomic particle or by radiation.&lt;/p&gt;

&lt;div style="margin-left: 5em; margin-right: 5em; margin-top: 2em; margin-bottom: 2em; padding: 16px; border: 1px solid #c0c0c0;  background-color: #f0f0f0;"&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Alpha_particle"&gt;Alpha particle strike&lt;/a&gt; - two protons plus two electrons, emitted when a heavy radioactive element decays into a lighter element. Alpha particles are so large that the chip packaging will normally block them, they are only a problem when something &lt;i&gt;inside&lt;/i&gt; the package undergoes radioactive decay.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Cosmic_rays"&gt;Cosmic ray strike&lt;/a&gt; - a high energy neutron (or other particle) emitted by the Sun. These particles are gradually absorbed by the Earth's atmosphere, so they are more of a problem in orbit and at high altitude. Cosmic rays can directly impact the silicon, or can hit a nearby atom and throw off neutrons which in turn cause a soft error.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Beta_particle"&gt;Beta particle strike&lt;/a&gt; - an electron, emitted when a neutron is converted into a proton + electron + antineutrino. Beta particles rarely hold enough energy to affect current silicon technology, alpha and cosmic ray strikes are more of a problem.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SqJRcrvqeJI/AAAAAAAAAZs/iZq_A7jeqhc/s320/dram.png" width="119" height="107" align="right" border="0" alt="A DRAM bit" title="Inspired by Space Invaders, no doubt."&gt;
Soft errors are usually discussed in the context of DRAM, where the problem was initially noticed. DRAM consists of a capacitor to store the bit, with a transistor to keep the capacitor charge stable. A capacitor is an energy storage circuit: it stores voltage. A particle strike on the capacitor will impart a large amount of energy, which can spontaneously change it to a 1 or, more rarely, overload its capacity such that the energy quickly escapes into the substrate and leaves the bit as a 0.&lt;/p&gt;

&lt;div style="clear: both;"&gt;&lt;/div&gt;
&lt;p&gt;Some quick searching will turn up a few facts about soft errors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Soft errors were first noted in the 1970s.&lt;/li&gt;
&lt;li&gt;The primary cause was the use of slightly radioactive isotopes in the chip packaging, such as lead (Pb-212).&lt;/li&gt;
&lt;li&gt;Materials in chip packaging are now carefully screened to substantially eliminate radioactivity.&lt;/li&gt;
&lt;li&gt;Soft errors are now very rare and mostly caused by cosmic rays.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll come back to these later.&lt;/p&gt;



&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Beyond DRAM&lt;/span&gt;

&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SqJSDM3P2KI/AAAAAAAAAZ0/bfkTBehOHek/s320/sram.png" width="227" height="206" border="0" align="left" alt="A 6 transistor SRAM bit" title="I really like Omnigraffle. http://www.omnigroup.com/applications/omnigraffle/"&gt;

&lt;br&gt;
&lt;p&gt;Soft errors are not confined to DRAM alone. Any circuit will glitch if hit by a sufficiently energetic particle - whether DRAM, SRAM, or a logic element. DRAM began to be affected by soft errors when the energy stored in the capacitor shrunk to be on the order of the energy induced by an alpha particle. SRAM was not initially affected because its cells are actively driven via 6 transistors, whose energy level is considerably higher. Nonetheless as silicon feature sizes have shrunk it is now quite possible for SRAM to suffer a soft error. Soft errors in logic elements are somewhat less noticeable in that they will correct themselves on the next clock cycle, while an error in a storage element will persist until it is rewritten.&lt;/p&gt;

&lt;p&gt;&lt;img style="padding:3px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SqJSR4W9PqI/AAAAAAAAAZ8/iQKhJK4Vwoo/s320/NehalemSRAM.jpg" width="256" height="177" border="0" align="right" alt="Intel Nehalem with SRAM highlighted" title="It looks like a patchwork quilt."&gt;
Modern CPUs include a great deal of SRAM on the die, comprising the caches, TLBs, reorder buffers, and numerous other uses. The image shown here is Intel's quad core &lt;a href="http://www.intel.com/technology/architecture-silicon/next-gen/"&gt;Nehalem&lt;/a&gt; die, with the SRAM areas highlighted and logic deemphasized (both based on my best guesses). SRAM is a significant fraction of the die. Many, many other ASIC and CPU designs contain similar or higher fractions of SRAM.&lt;/p&gt;

&lt;p&gt;What impact can a bitflip in the SRAM have? Consider that there is just one bit difference between the following two instruction opcodes. A bitflip can make the software come up with results which should be impossible.&lt;/p&gt;

&lt;div style="margin: 1em 5em 1em 5em; font-family: monospace; font-size: x-small; line-height: 1.3em;"&gt;
ADD R1,1&lt;br&gt;
ADD R1,32769
&lt;/div&gt;

&lt;p&gt;Even more bizarrely a bitflip could change some random instruction into a memory reference, such as a load or store. As the register being dereferenced would likely not contain a valid pointer, the process would segfault for inexplicable reasons.&lt;/p&gt;

&lt;p&gt;To prevent this problem Intel and all major CPU vendors protect their caches and other on-chip memories using &lt;a href="http://en.wikipedia.org/wiki/Error_detection_and_correction"&gt;Error Correcting Codes&lt;/a&gt;, but many ASIC designs do not. They might implement parity, but on-chip ASIC memories commonly have no error checking at all. A soft error will simply corrupt whatever was in the SRAM, which will only be noticed if it causes the ASIC to misbehave in some perceptible way.&lt;/p&gt;

&lt;p&gt;What happens if a particle strike causes the hardware to misbehave, or to get the wrong answer? Usually, we blame the software. It must be some weird bug.&lt;/p&gt;



&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Back To The Future&lt;/span&gt;
&lt;p&gt;Returning to the earlier list of common facts about soft errors, lets focus on the last two.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Materials in chip packaging are now carefully screened to substantially eliminate radioactivity.&lt;/li&gt;
&lt;li&gt;Soft errors are now very rare and mostly caused by cosmic rays.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many different materials used in a finished chip, beyond the silicon die and the gold wires connecting to its pins. The chip package is plastic or ceramic, which is composed of a host of different elements including boron. Solder bonds the wires to the pins. Solder used to be mostly lead, later tin, and might now be a polymer. There are heat spreading compounds and shock absorption goo, which are often organic polymers. Some of these materials are naturally slightly radioactive. For example, in nature Lead (Pb-208) contains traces of Pollonium (Po212) which will emit alpha particles and decay into Pb-208. Similarly &lt;a href="http://en.wikipedia.org/wiki/Boron"&gt;boron-10&lt;/a&gt;  is more prone to fission than boron-11 - or so they tell me, I've no idea why.&lt;/p&gt;

&lt;p&gt;Modern chip packaging uses strained versions of these materials, to reduce the level of undesirable isotopes and leave purified inert material behind. This is an expensive process. Each new generation of silicon imposes more stringent requirements, making them even more costly. It is crucial that the correct materials be used... and this is where human error can creep in.&lt;/p&gt;

&lt;p&gt;Using the wrong packaging materials increases alpha emissions to the point where the silicon will experience an unacceptable soft error rate. Yet to control costs it is also important to not overshoot the alpha emission requirements by using a more expensive material than necessary. So each chip design may use a different mix of materials depending on its process technology, die size, and the amount of SRAM it contains. The manufacturer will have checks in place to ensure the correct materials are used, but mistakes can occur. Sometimes a batch of chips is produced which suffers an unusually high soft error rate. When this happens the manufacturer is generally loathe to admit it, and will quietly replace the chips with a corrected batch. One recent case where the problem was too widespread to cover up was with the cache of the Ultrasparc-II CPU from Sun Microsystems, see &lt;a href="http://www.actel.com/documents/SER_FAQ.pdf"&gt;point #5 of an Actel FAQ&lt;/a&gt; on the topic for more details.&lt;/p&gt;


&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;The Moral of the Story&lt;/span&gt;
&lt;p&gt;
&lt;a href="http://www.flickr.com/photos/fotero/434296609/"&gt;&lt;img style="padding:8px; border:0px;" src="http://1.bp.blogspot.com/_WibILqsOlLg/SqJVnG9ku4I/AAAAAAAAAaE/AXxs-zmp5q4/s320/tribar.png" width="99" height="120" border="0" align="right" alt="The impossible triangle, a tribar" title="Original image by Fotero, licensed under Creative Commons"&gt;&lt;/a&gt;

If you are working on low level software for a chip and run into bizarre errors, you should suspect a software problem &lt;i&gt;first&lt;/i&gt;. Soft errors really are rare, and the manufacturing screwups described above are very uncommon. If the problem is repeatable, even if it has only happened twice, it is not a soft error. Particle strikes are too random for that. However if you keep running into different symptoms where you think &amp;quot;but that is impossible...&amp;quot; you should consider the possibility that the problem really &lt;i&gt;is&lt;/i&gt; impossible and was introduced by a bitflip. You should start checking whether the problems are confined to a particular batch of parts, or only produced in a certain range of dates. If so, it could be that batch of parts has a problem with the packaging materials.&lt;/p&gt;



&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Other resources&lt;/span&gt;
&lt;p&gt;While researching this post I came across a few additional sources of information which I found fascinating, but did not have a good place to link to them. They are presented here for your edification and bemusement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An &lt;a href="http://institutes.lanl.gov/data/fdata/papers/IEEE_ASC_Q_errors.pdf"&gt;analysis&lt;/a&gt; of the high soft error rate of the ASC Q supercomputer at LLNL. These errors were cosmic ray induced, not due to a badly packaged batch of chips. The part of the system in question did not implement ECC to correct errors, only parity to detect them and crash.&lt;/li&gt;
&lt;li&gt;Cypress Semiconductor &lt;a href="http://www.cypress.com/?rID=38011"&gt;published a book&lt;/a&gt; to explain soft errors to their customers.&lt;/li&gt;
&lt;li&gt;Fujitsu has a simulator to predict soft error rates, called &lt;a href="http://img.jp.fujitsu.com/downloads/jp/jmag/vol51-5/paper09.pdf"&gt;NISES&lt;/a&gt;. The linked PDF is mostly in Japanese, but the images are fascinating and very illustrative.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post was many years in the making.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-427871956314027663?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=zeAGK4-x4RM:7BZqnFl2fCI:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=zeAGK4-x4RM:7BZqnFl2fCI:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=zeAGK4-x4RM:7BZqnFl2fCI:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=zeAGK4-x4RM:7BZqnFl2fCI:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=zeAGK4-x4RM:7BZqnFl2fCI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=zeAGK4-x4RM:7BZqnFl2fCI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=zeAGK4-x4RM:7BZqnFl2fCI:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=zeAGK4-x4RM:7BZqnFl2fCI:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/zeAGK4-x4RM" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=427871956314027663" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/427871956314027663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/427871956314027663?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/soft-errors-are-hard-problems.html" title="Soft Errors Are Hard Problems" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/SqJRcrvqeJI/AAAAAAAAAZs/iZq_A7jeqhc/s72-c/dram.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C04CR3s_eyp7ImA9WxNRF00.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-5455015824470850823</id><published>2009-09-11T13:46:00.000-07:00</published><updated>2009-09-11T13:46:06.543-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T13:46:06.543-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Motorola Mobile Meanderings</title><content type="html">&lt;p&gt;On September 10th Motorola announced the &lt;a href="http://www.motorola.com/Consumers/US-EN/Consumer-Product-and-Services/Mobile-Phones/Motorola-CLIQ-US-EN"&gt;CLIQ&lt;/a&gt;, its first &lt;a href="http://developer.android.com/guide/basics/what-is-android.html"&gt;Android&lt;/a&gt; phone and a product which a good friend of mine has labored over for quite some time.&lt;/p&gt;

&lt;br/&gt;
&lt;center&gt;&lt;img style="padding:3px; border:0px;" width="400" height="369" border="0" src="http://1.bp.blogspot.com/_WibILqsOlLg/Sqq2Lc4P6EI/AAAAAAAAAbg/yIjKvnsBiuw/s400/cliq.jpg"&gt;&lt;/center&gt;

&lt;br/&gt;
&lt;p&gt;For many years I have used my trusty &lt;a href="http://www.phonescoop.com/phones/phone.php?p=275"&gt;Sony-Ericsson T616&lt;/a&gt;, but I admit it might be getting a bit dated. I decided to compare the two devices to see whether its time for me to take up a new phone.&lt;/p&gt;

&lt;center&gt;&lt;table style="border: none; empty-cells: hide;" cellpadding="5"&gt;
&lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;T616&lt;br/&gt;&lt;center&gt;&lt;img style="padding:1px; border:0px;" border="0" height="20" width="45" src="http://1.bp.blogspot.com/_WibILqsOlLg/Sqq2ajYtkII/AAAAAAAAAbo/gm_WVfrscwE/s320/t616sml.jpg"&gt;&lt;/center&gt;&lt;/td&gt;
    &lt;td&gt;CLIQ&lt;br/&gt;&lt;center&gt;&lt;img style="padding:1px; border:0px;" border="0" height="30" width="38" src="http://1.bp.blogspot.com/_WibILqsOlLg/Sqq2mml0QRI/AAAAAAAAAbw/fYsdzQ23C0M/s320/cliqsml.jpg"&gt;&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
    &lt;td&gt;Cracked LCD screen?&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ccffcc;"&gt;Y&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ffcccc;"&gt;N&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
    &lt;td&gt;Broken down arrow key?&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ccffcc;"&gt;Y&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ffcccc;"&gt;N&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
    &lt;td&gt;Wallpaper picture of my Daughter?&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ccffcc;"&gt;Y&lt;/td&gt;
    &lt;td style="text-align: center; background-color: #ffcccc;"&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/center&gt;

&lt;br/&gt;
&lt;p&gt;As you can see, clearly I cannot replace my T616 until Motorola rectifies these glaring omissions in the CLIQ. The cracked screen and non-functional arrow key could both be achieved via sufficiently rough handling. Frankly I don't know how Motorola would obtain pictures of my daughter to use as wallpaper, though I might be willing to accept this little flaw and add my own wallpaper later.&lt;/p&gt;

&lt;p&gt;This chart shows that my T616 is the perfect phone, but I'm in a generous mood. The first person to offer me enough money for me to buy a CLIQ, takes it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-5455015824470850823?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=rowPMb_98is:TFiFLGYhrdM:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=rowPMb_98is:TFiFLGYhrdM:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=rowPMb_98is:TFiFLGYhrdM:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=rowPMb_98is:TFiFLGYhrdM:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=rowPMb_98is:TFiFLGYhrdM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=rowPMb_98is:TFiFLGYhrdM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=rowPMb_98is:TFiFLGYhrdM:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=rowPMb_98is:TFiFLGYhrdM:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/rowPMb_98is" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=5455015824470850823" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/5455015824470850823?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/5455015824470850823?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/motorola-mobile-meanderings.html" title="Motorola Mobile Meanderings" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_WibILqsOlLg/Sqq2Lc4P6EI/AAAAAAAAAbg/yIjKvnsBiuw/s72-c/cliq.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUAAQHs7cCp7ImA9WxNRFE0.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-3213799557469226868</id><published>2009-09-08T04:02:00.000-07:00</published><updated>2009-09-08T04:02:21.508-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-08T04:02:21.508-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="architecture" /><title>Infinite Arrays of Tweeples</title><content type="html">&lt;p&gt;&lt;img style="padding:3px; border:0px;" src="http://3.bp.blogspot.com/_WibILqsOlLg/SqTsiJPpILI/AAAAAAAAAbY/bjjvvK704N8/s640/followers.png" width="90" height="416" border="0" align="right" alt="Twitter followers list" title="Fortunately I dont measure myself by my number of followers. I mean, wow."&gt;
&lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; is somewhat out of the range of topics I normally cover here, but I promise we'll come around to a software development angle by the end of this post.&lt;/p&gt;

&lt;p&gt;When you &lt;a href="http://twitter.com/dgentry"&gt;follow someone&lt;/a&gt; on twitter, you appear in their &lt;a href="http://twitter.com/dgentry/followers"&gt;followers&lt;/a&gt; list and they appear in your &lt;a href="http://twitter.com/dgentry/following"&gt;following&lt;/a&gt; list. New entries appear at the top, so the newest follower will be the first entry in your list. Recently I noticed an exception to this sort ordering, when &lt;a href="http://twitter.com/scobleizer"&gt;someone&lt;/a&gt; who had been following a long time ago and later unfollowed decided to follow again. I received the notification email from twitter, yet he wasn't at the top of the list of followers. Instead he appeared much further down in the listing, off the first page. That is where he was when he followed me the first time, many months ago. This entry disappeared when he  unfollowed, and when he re-followed he ended up back in that same place. Why would that be?&lt;/p&gt;


&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Possibility #1: Timestamp&lt;/span&gt;
&lt;p&gt;The first possibility, and more likely the correct one, is that twitter tracks the timestamp of every new follow and chooses not to update it on a subsequent refollow. No matter how many times you have followed/unfollowed, you retain the timestamp of the very first time and will show up in the followers list at that position.&lt;/p&gt;

&lt;p&gt;If an unfollow+refollow was sufficient to move you back up to the top of the list of followers, the &lt;a href="http://jetsam.geekhold.com/tweetbots-getting-smarter"&gt;bots&lt;/a&gt; would do it all the time to make it more likely you'd follow them back. Yet this is a boring root cause. So lets consider a second possibility which is more illustrative to software development.&lt;/p&gt;



&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;Possibility #2: Array Deletion&lt;/span&gt;
&lt;p&gt;Twitter operates at a scale where &lt;a href="http://www.scribd.com/doc/16878322/Fixing-Twitter-Improving-the-Performance-and-Scalability-of-the-Worlds-Most-Popular-Microblogging-Site"&gt;performance optimization&lt;/a&gt; is essential. If they are not cognizant about performance the wheels fly off and users start to see the &lt;a href="http://www.readwriteweb.com/archives/the_story_of_the_fail_whale.php"&gt;Fail Whale&lt;/a&gt;. An area of particular importance is the list of followers, as the backend infrastructure has to traverse it for every tweet. It is possible that twitter implemented the followers list as an array in memory instead of a linked list, presumably to get better locality. The classic drawback of an array is deletion: you cannot delete an element from the middle without moving all subsequent elements into the hole thus created. To avoid this compaction a &amp;quot;deleted&amp;quot; or &amp;quot;active&amp;quot; bit is commonly kept for each element, allowing deleted entries to be left in place but skipped without processing.&lt;/p&gt;

&lt;!-- http://scobleizer.com/2009/08/05/you-are-so-unfollowed/ --&gt;

&lt;p&gt;When &lt;a href="http://friendfeed.com/scobleizer/4bc0fa2c/i-am-going-to-unfollow-everyone-tonight-on"&gt;Scobleizer unfollowed everyone&lt;/a&gt; it would have resulted in holes in the followers list of 106,000 different accounts, entries with the deleted bit set.&lt;/p&gt;

&lt;center&gt;&lt;img style="padding:3px; border:0px;" src="http://3.bp.blogspot.com/_WibILqsOlLg/SqTqsA1kiUI/AAAAAAAAAbE/NL2oNMN1HMI/s640/deletebits.png" width="339" height="165" border="0" alt="Array with deleted bits" title="My, thats a lot of holes in that thar list."&gt;&lt;/center&gt;

&lt;p&gt;I suspect that Twitter does not immediately compact these arrays, so long as the ratio of holes/filled entries is tolerable. When Scobleizer decided to re-follow me the twitter backend located the earlier, deleted entry and flipped the bit back to active.&lt;/p&gt;

&lt;center&gt;&lt;img style="padding:3px; border:0px;" src="http://3.bp.blogspot.com/_WibILqsOlLg/SqTqusk5wPI/AAAAAAAAAbM/7nQ9K7llvH0/s640/refollow.png" width="369" height="217" border="0" alt="Array after refollowing" title="I made it back onto the list! Yay!"&gt;&lt;/center&gt;

&lt;p&gt;Thus the newly restored entry will re-appear in the followers list, but not as the top most entry. It will re-appear at its existing position within the array. This, or a similar implementation choice of retaining deleted entries in some way, could be why re-follows do not appear at the top of the list.&lt;/p&gt;


&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 115%;"&gt;The Moral of the Story&lt;/span&gt;
&lt;p&gt;Optimization is fine, and &lt;a href="http://en.oreilly.com/velocity2009/public/schedule/detail/7479"&gt;absolutely crucial to function&lt;/a&gt; at Twitter scale, but one must to be careful when an optimization changes user-visible behavior. This is particularly true for social media, where we're explicitly conversing with other humans and ascribe human motivations to their actions. Twitter's handling of deleted and re-added follows can cause considerable consternation, because to the casual observer it appears the person followed but then immediately unfollowed. &lt;a href="http://jetsam.geekhold.com/inconsistent-twitter-follower-sort-ordering-n"&gt;It can seem judgmental.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, I am most likely completely wrong about Twitter's implementation using arrays. It wouldn't be the first time I've made a &lt;a href="http://codingrelic.geekhold.com/2008/03/premature-optimization-for-fun-and.html"&gt;complete fool&lt;/a&gt; out of myself in a blog post. Its cathartic, in a way. Perhaps I'll do it more often.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-3213799557469226868?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=sA-0PgyB15w:5J0Un_vxU3E:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=sA-0PgyB15w:5J0Un_vxU3E:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=sA-0PgyB15w:5J0Un_vxU3E:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=sA-0PgyB15w:5J0Un_vxU3E:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=sA-0PgyB15w:5J0Un_vxU3E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=sA-0PgyB15w:5J0Un_vxU3E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=sA-0PgyB15w:5J0Un_vxU3E:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=sA-0PgyB15w:5J0Un_vxU3E:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/sA-0PgyB15w" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=3213799557469226868" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3213799557469226868?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3213799557469226868?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/09/infinite-arrays-of-tweeples.html" title="Infinite Arrays of Tweeples" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_WibILqsOlLg/SqTsiJPpILI/AAAAAAAAAbY/bjjvvK704N8/s72-c/followers.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UESHg9fCp7ImA9WxNSEUw.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-3890993881523375479</id><published>2009-08-24T05:00:00.000-07:00</published><updated>2009-08-24T05:00:09.664-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T05:00:09.664-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Product Development" /><title>Plummeting Down the Chasm</title><content type="html">&lt;p&gt;&lt;img style="padding:5px; border:0px; float: right;" src="http://2.bp.blogspot.com/_WibILqsOlLg/SpFW0mn8KzI/AAAAAAAAAZM/Vxa6QefSC1c/s320/bookcover.jpg" width="55" height="86" border="0" alt="Crossing the Chasm book cover" title="This is the paperback edition published in 1995."&gt;&lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Crossing_the_Chasm"&gt;Crossing the Chasm&lt;/a&gt;&lt;/i&gt; is a seminal book in technology marketing, whose ideas quickly spread through the industry. Originally written in 1991 by &lt;a href="http://en.wikipedia.org/wiki/Geoffrey_Moore"&gt;Geoffrey Moore&lt;/a&gt;, it showed a new take on the technology adoption lifecycle. The lifecycle starts with tech enthusiasts willing to buy an immature product and runs through the majority buyers who make up the bulk of the market, finally trailing off when market saturation is reached. It had been commonly depicted as a bell curve:&lt;/p&gt;

&lt;br clear=right/&gt;

&lt;div style="font-size:x-small; text-align: center;" xmlns:cc="http://creativecommons.org/ns#" about="http://en.wikipedia.org/wiki/File:Technology-Adoption-Lifecycle.png"&gt;&lt;a rel="cc:attributionURL" href="http://en.wikipedia.org/wiki/File:Technology-Adoption-Lifecycle.png"&gt;&lt;img style="padding:3px; border:0px;" src="http://2.bp.blogspot.com/_WibILqsOlLg/SpFXDaI_EyI/AAAAAAAAAZU/_T63c9Yerwg/s640/wiki_talcsml.png" width="512" height="204" border="0" alt="Technology Adoption Life Cycle" title="Original illustration by Craig Chelius (via WikiMedia), licensed under Creative Commons, modified by DGentry to remove the chasm."&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Moore's key observation is that while the bell curve implies there is a smooth transition from early market to majority, in reality the buyers in the early market are fundamentally different from the majority that comes later. Technology companies who don't appreciate this gap will stumble and often fail once they saturate the small pool of early buyers. Moore referred to this gap as &amp;quot;the chasm.&amp;quot;&lt;/p&gt;

&lt;div style="font-size:x-small; text-align: center;" xmlns:cc="http://creativecommons.org/ns#" about="http://en.wikipedia.org/wiki/File:Technology-Adoption-Lifecycle.png"&gt;&lt;a rel="cc:attributionURL" href="http://en.wikipedia.org/wiki/File:Technology-Adoption-Lifecycle.png"&gt;&lt;img style="padding:3px; border:0px;" src="http://2.bp.blogspot.com/_WibILqsOlLg/SpFXGjivOdI/AAAAAAAAAZc/y1Zp1QY24sE/s640/wiki_chasmsml.png" width="512" height="204" border="0" alt="Technology Adoption Life Cycle" title="Original illustration by Craig Chelius (via WikiMedia), licensed under Creative Commons."&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Early adopters are visionaries. They are willing to look at an immature product and figure out how to use it in their operations to get a competitive advantage. They will sponsor integration work within their IT departments, and generate long lists of product feedback to better fit their needs. They are fundamentally different from the majority buyers in that they will look at an interesting product and figure out what problem it can solve. The majority market comes from the opposite direction with a problem to solve, looking for a solution. Product planning and marketing which works in the early part of a product lifecycle will fail utterly later in the game.&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size: 125%;"&gt;Yon Chasm Approacheth&lt;/span&gt;

&lt;p&gt;It is quite possible to get stuck in the early market, continuously trying to meet the needs of early adopters and never enjoying the big sales of the majority market. Having spent the last several years in this predicament, I'll offer my version of the lifecycle chart. What it lacks in precision, it makes up for in snark.&lt;/p&gt;

&lt;br/&gt;
&lt;div style="font-size:x-small; text-align: center;" xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/supermac/3578004311/"&gt;&lt;a rel="cc:attributionURL" href="http://www.flickr.com/photos/supermac/3578004311/"&gt;&lt;img style="padding:3px; border:0px;" src="http://2.bp.blogspot.com/_WibILqsOlLg/SpFXJQqJkSI/AAAAAAAAAZk/6AxwL7ULRmY/s640/chasm.jpg" width="512" height="123" border="0" alt="Rope bridge with gaps" title="Original photo by supermac, licensed under Creative Commons, modified by DGentry to illustrate Crossing the Chasm."&gt;&lt;/a&gt;&lt;/div&gt;

&lt;br/&gt;
&lt;p&gt;As a development engineer it can be difficult to tell how well the sales cycle is working as one rarely gets direct visibility, but the indirect evidence is plentiful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If nearly every deal comes with a list of new product features to be implemented, you have not crossed the chasm.&lt;/li&gt;

&lt;li&gt;If in every medium to large deal it is not clear whether the cost of getting the business is greater than the revenue it would bring, you have not crossed the chasm.&lt;/li&gt;

&lt;li&gt;If every deal is &amp;quot;high touch,&amp;quot; requiring multiple visits by a salesperson and sales engineer and possibly a consultation with the development team, you have not crossed the chasm.&lt;/li&gt;

&lt;li&gt;If your product cannot be sold via a web site but instead always requires an evaluation period and report, you have not crossed the chasm.&lt;/li&gt;

&lt;li&gt;If every customer is using a different subset of the product functionality, you have not crossed the chasm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important: if the company does not realize that the real problem is in the approach to the market, all of these things will be &lt;b&gt;blamed on the product&lt;/b&gt;. The reasoning will be that &amp;quot;if we just pound out a few more of these deals, we'll have finally implemented everything that everybody wants and sales will take off.&amp;quot; There may even be an element of truth in this sentiment, if the product shipped early before its natural feature set was complete. However if the company has not crossed the chasm, the fundamental problem is elsewhere.&lt;/p&gt;

&lt;p style="margin-left: 5em; margin-right: 5em; margin-top: 2em; margin-bottom: 2em; padding: 16px; border: 1px dotted grey; background-color: LightGrey;"&gt;You are not getting a list of feature requirements because the product is incomplete, but because &lt;b&gt;you are selling to the type of customer who generates lists of requirements&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;You are getting that list of requirements because you are still selling into the visionary and early adopter segments of the market, the people who are willing to think about how best to integrate the product into their operations.  If you were selling into the mainstream market there would be no list of requirements because the mainstream won't do an extensive integration on their own. The product either meets their needs or it doesn't, and you'll either get the sale or you won't. In the mainstream there will be no back and forth of what the product could do to win the business. At most, the mainstream buyer might tell you why you lost the business.&lt;/p&gt;

&lt;p&gt;Don't get stuck wandering around in the chasm. Trust me, it sucks.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-3890993881523375479?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=9DUfSEriMhs:C4DrZTGzo9Y:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=9DUfSEriMhs:C4DrZTGzo9Y:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=9DUfSEriMhs:C4DrZTGzo9Y:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=9DUfSEriMhs:C4DrZTGzo9Y:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=9DUfSEriMhs:C4DrZTGzo9Y:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=9DUfSEriMhs:C4DrZTGzo9Y:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=9DUfSEriMhs:C4DrZTGzo9Y:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=9DUfSEriMhs:C4DrZTGzo9Y:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/9DUfSEriMhs" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=3890993881523375479" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3890993881523375479?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/3890993881523375479?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/08/plummeting-down-chasm.html" title="Plummeting Down the Chasm" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_WibILqsOlLg/SpFW0mn8KzI/AAAAAAAAAZM/Vxa6QefSC1c/s72-c/bookcover.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;C0cFR3o6eSp7ImA9WxNTGEo.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-299881558458694444</id><published>2009-08-21T06:31:00.000-07:00</published><updated>2009-08-21T09:10:16.411-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-21T09:10:16.411-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Product Development" /><title>Smartbooks and Handheld PCs</title><content type="html">&lt;p&gt;Intel markets the &lt;a href="http://www.intel.com/technology/atom/"&gt;Atom&lt;/a&gt; processor for netbooks. It trades lower processing power for very low power consumption, and is quite inexpensive in large quantities. These are product features where ARM/PowerPC/MIPS have long focussed, though they have aimed at non-PC form factor devices. Now, a new round of &lt;a href="http://www.engadget.com/tag/smartbook"&gt;small laptops&lt;/a&gt; is hitting the market using non-x86 processors with either &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Windows_CE"&gt;Windows CE&lt;/a&gt; or a Linux software stack like Google's &lt;a href="http://code.google.com/android/"&gt;Android&lt;/a&gt; or, eventually, &lt;a href="http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html"&gt;Chrome OS&lt;/a&gt;. Most notably, &lt;a href="http://arstechnica.com/open-source/news/2009/08/new-dell-arm-combo-poised-to-take-on-wintel-netbooks.ars"&gt;Dell&lt;/a&gt; appears to be on the verge of introducing such a device - the true measure of whether a product category has entered the mainstream. These devices are generally called Smartbooks, owing to &lt;a href="http://www.hellosmartbook.com/index.html"&gt;Qualcomm's extensive marketing push&lt;/a&gt; for its ARM Snapdragon chips in such a role.&lt;/p&gt;

&lt;p&gt;
&lt;img style="padding:3px; border:0px; margin-left: 3em;" align=right src="http://4.bp.blogspot.com/_WibILqsOlLg/So7Grdc26tI/AAAAAAAAAZE/Ny_707d0o9I/s400/vademclio.jpg" width="318" height="311" border="0" alt="Vadem Clio CL-1050" title="When closed the screen arms cover the ports. Very clever."&gt;
What strikes me about these devices is that we've been down a similar road before. In the late 1990s there was a flurry of activity around &lt;a href="http://en.wikipedia.org/wiki/Handheld_PC"&gt;HandHeld PCs&lt;/a&gt;, which were relatively small and inexpensive compared to the laptops of the day. They typically used MIPS processors, ran Windows CE, and supplied basic word processing and communications software. Handheld PCs didn't last long on the market, and Microsoft ceased work on the software after just two years. The devices simply were not useful enough when compared to a full laptop.&lt;/p&gt;

&lt;p&gt;This is another example of how infrastructure and market can make more of a contribution to the success of a new product as its design. If a product is too early, it won't get enough traction to drag the rest of the environment along. In 2009 these devices can depend on a fast wireless infrastructure and plentiful cloud-hosted applications, which did not exist in 1999. The world has changed.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-299881558458694444?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=DDeq1OJpFzA:8CsOK0gQ7Uw:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=DDeq1OJpFzA:8CsOK0gQ7Uw:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=DDeq1OJpFzA:8CsOK0gQ7Uw:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=DDeq1OJpFzA:8CsOK0gQ7Uw:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=DDeq1OJpFzA:8CsOK0gQ7Uw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=DDeq1OJpFzA:8CsOK0gQ7Uw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=DDeq1OJpFzA:8CsOK0gQ7Uw:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=DDeq1OJpFzA:8CsOK0gQ7Uw:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/DDeq1OJpFzA" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=299881558458694444" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/299881558458694444?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/299881558458694444?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/08/smartbooks-and-handheld-pcs.html" title="Smartbooks and Handheld PCs" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_WibILqsOlLg/So7Grdc26tI/AAAAAAAAAZE/Ny_707d0o9I/s72-c/vademclio.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;AkENQn87eCp7ImA9WxNXEEk.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-7416024974044758567</id><published>2009-08-18T05:30:00.000-07:00</published><updated>2009-09-27T03:51:33.100-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T03:51:33.100-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Virtual Machines" /><category scheme="http://www.blogger.com/atom/ns#" term="CPU" /><title>Virtual Machines And Manual Transmissions</title><content type="html">&lt;img style="padding:3px; border:0px; margin-left: 3em;" align=right src="http://3.bp.blogspot.com/_WibILqsOlLg/SoqbNLqmdcI/AAAAAAAAAYo/95fxChax0z8/s200/stickshift.jpg" width="150" height="200" border="0" alt="Stick Shift Knob" title="Yes, this is my car."&gt;

&lt;p&gt;I've chosen a manual transmission for every vehicle I've purchased. It is a personal preference, I like the feeling of control over the engine and the ability to trade power for torque. Driving a stick shift was also an advantage in school: practically nobody knew how to drive it, so nobody could borrow my car.&lt;/p&gt;

&lt;p&gt;For software development I code mostly in C, which is a rather thin layer on top of the machine. Even C++, while still considered a low-level language, nonetheless implements significantly more abstraction. Consider the following simple example of incrementing a variable in C and in C++:&lt;/p&gt;


&lt;table border="0" cellpadding="8px"&gt;

&lt;tr valign="top"&gt;
&lt;td width="45%"&gt;
&lt;b&gt;C:&lt;/b&gt;
&lt;pre style="font-family: monospace; font-size: small; line-height: 1.1em;"&gt;
int val = 0;

int incr() {
    val++;
}
&lt;/pre&gt;&lt;/td&gt;

&lt;td&gt;
&lt;b&gt;C++:&lt;/b&gt;
&lt;pre style="font-family: monospace; font-size: small; line-height: 1.1em;"&gt;
class exi {
    int val;

    public:
        exi() { val = 0; };

        int incr() {
            val++;
        }
};
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;Note that in neither case is incr() declared to take an argument. We'll use one of my &lt;a href="http://codingrelic.geekhold.com/2008/03/secret-life-of-volatile.html"&gt;favorite&lt;/a&gt; &lt;a href="http://codingrelic.geekhold.com/2008/07/gdb-lies-to-you.html"&gt;techniques&lt;/a&gt;, &lt;a href="http://codingrelic.geekhold.com/2009/02/inadvisable-externing.html"&gt;disassembling&lt;/a&gt; the binary to see how it works. This time we're looking at PowerPC opcodes.&lt;/td&gt;&lt;/tr&gt;

&lt;tr valign="top"&gt;
&lt;td&gt;&lt;table style="font-family: monospace; font-size: x-small; line-height: 1.1em;" border="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;_main:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;bl _incr&lt;/td&gt;    &lt;td&gt;&amp;nbsp;&lt;i&gt;branch to incr()&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;    &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;_incr:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;mfspr r9,lr&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;address of val&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;lwz  r2,0xbc(r9)&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;fetch val&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;addi r2,r2,0x1&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;increment&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;stw  r2,0xbc(r9)&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;store new val&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;blr&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;return&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;

&lt;td&gt;&lt;table style="font-family: monospace; font-size: x-small; line-height: 1.1em;" border="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;_main:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;i&gt;&amp;nbsp;... much C++ object init removed...&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="font-weight: bold;"&gt;&lt;td&gt;&amp;nbsp;addi r3,r1,0x38&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;&lt;u&gt;object addr in arg0&lt;/u&gt;&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;bl __ZN6exi4incrEv&lt;/td&gt;    &lt;td&gt;&amp;nbsp;&lt;i&gt;branch to exi::incr()&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;    &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;__ZN6exi4incrEv:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;lwz  r2,0x0(r3)&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;fetch val from *arg0&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;addi r2,r2,0x1&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;increment&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;stw  r2,0x0(r3)&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;store new val&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;blr&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;i&gt;return&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;/table&gt;

&lt;br/&gt;

&lt;p&gt;Though the C++ source code does not show an argument to exi::incr(), at the machine level there nonetheless is one. The object address is passed as the first argument. Passing the object is necessary for C++ to handle &amp;quot;this&amp;quot; object - it has to have a pointer to operate on.&lt;/p&gt;

&lt;p&gt;In low level languages you can generally see the relationship from source to the resulting machine code, even when significant compiler optimization is done. As we move to higher level languages, the abstractions between the source and machine code grow ever larger. C++ is somewhat higher level than C, and at the machine level the mapping from instructions back to source code is less clear. More abstract languages like Java, Python, and C# compile to a virtual machine running on top of the real system. If one gathered an instruction trace of CPU execution, one would be hard-pressed to correlate these instructions back to the source code they implement.&lt;/p&gt;

&lt;br/&gt;&amp;nbsp;&lt;br/&gt;
&lt;span style="font-weight: bold; font-size:105%;"&gt;Foreshadowing&lt;/span&gt;
&lt;p&gt;One can see the day coming when manual transmissions will be unavailable in most car models. &lt;a href="http://en.wikipedia.org/wiki/Continuously_variable_transmission"&gt;Continuously variable transmissions&lt;/a&gt; were an early indication of this trend, with an essentially infinite number of gearing ratios that could only be effectively controlled by an engine computer. Hybrid vehicles have a complex transmission which meshes the output of two motors, and again can only be controlled by computer. Future vehicles will likely have an entirely electric drivetrain, with no need for a conventional transmission at all. The simple fact is that the engine computer can do a far better job of optimizing the behavior of the drivetrain than I can.&lt;/p&gt;

&lt;p&gt;I'm currently digging in to the low level aspects of virtual machines. Running compilation just-in-time as part of a virtual machine has several notable advantages over static compilation with gcc:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gcc's optimization improves if you compile with profiling, run the program, and then compile again. This is so annoying that it is hardly ever done. A virtual machine &lt;i&gt;always&lt;/i&gt; has profiling data available, as it interprets the bytecodes for a while before running the JIT.&lt;/li&gt;
&lt;li&gt;gcc's profile-guided optimization is done in advance, on a representative corpus of input data which the programmer supplies. If the program operates on inputs which differ substantially from this, its performance will not be optimal. The JIT optimization is always done with the real data as profiling input.&lt;/li&gt;
&lt;li&gt;gcc can optimize for a specific CPU pipeline, such as Core2 vs NetBurst vs i486. One is trading off performance improvement on the favored CPU versus degradation on other CPUs. The JIT can know the specific type of CPU being used and can optimize accordingly.&lt;/li&gt;
&lt;li&gt;gcc can do static constant propagation across subroutines. That is, if a constant NULL is passed to a function gcc can create a version of that function which will eliminate any unreachable code. The JIT can create optimal versions of functions tuned for specific arguments dynamically, whether they are constant or variable. It just has to validate that the arguments still match the expected, and it is free to jump back to the interpreted bytecode on a mismatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should be fun. Some initial thoughts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modern CPUs have extensive branch prediction and speculative execution features, to keep it from spending all its time stalled for the outcome of a branch decision. What happens when we have a lot more big loops with straight line code, where the JIT has optimized all the conditionals up to sanity checks at the entry to the function?&lt;/li&gt;
&lt;li&gt;Does widespread use of JIT mean that &lt;a href="http://en.wikipedia.org/wiki/Very_long_instruction_word"&gt;VLIW&lt;/a&gt; architectures become more viable? VLIW is particularly dependent on the compiler to match the code to available hardware resources, which a JIT is better positioned to tackle.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-7416024974044758567?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=MHbEtu0GSgc:pKnBEg1bphc:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=MHbEtu0GSgc:pKnBEg1bphc:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=MHbEtu0GSgc:pKnBEg1bphc:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=MHbEtu0GSgc:pKnBEg1bphc:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=MHbEtu0GSgc:pKnBEg1bphc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=MHbEtu0GSgc:pKnBEg1bphc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=MHbEtu0GSgc:pKnBEg1bphc:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=MHbEtu0GSgc:pKnBEg1bphc:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/MHbEtu0GSgc" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=7416024974044758567" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/7416024974044758567?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/7416024974044758567?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/08/virtual-machines-and-manual.html" title="Virtual Machines And Manual Transmissions" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_WibILqsOlLg/SoqbNLqmdcI/AAAAAAAAAYo/95fxChax0z8/s72-c/stickshift.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEUCSX85cSp7ImA9WxJaGUQ.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-8466768608118301038</id><published>2009-08-11T05:01:00.000-07:00</published><updated>2009-08-11T05:04:28.129-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-11T05:04:28.129-07:00</app:edited><title>blog.8.11.2009 &lt; /dev/random</title><content type="html">&lt;br/&gt;
&lt;p&gt;A while ago I wrote a &lt;a href="http://codingrelic.geekhold.com/2009/04/more-google-app-engine-feedflares.html"&gt;FeedFlare for FriendFeed&lt;/a&gt;, my second Google App Engine project. Monday morning, friendfeed.com &lt;a href="http://blog.friendfeed.com/2009/08/friendfeed-accepts-facebook-friend.html"&gt;announced&lt;/a&gt; that it has been acquired by Facebook. Anybody want to buy a slightly used FeedFlare?&lt;/p&gt;

&lt;br/&gt;
&lt;hr width="80%"&gt;
&lt;br/&gt;

&lt;p&gt;A year ago I wrote about the importance of &lt;a href="http://codingrelic.geekhold.com/2008/08/opensourcemycompanycom.html"&gt;publishing the GPLd&lt;/a&gt; source used in commercial products, to avoid the public relations nightmare that comes of being accused of a GPL violation. One of the points in that article was of the &lt;a href="http://www.softwarefreedom.org/news/2008/jul/21/busybox"&gt;SFLC suing Extreme Networks&lt;/a&gt;. I'm happy to report that the suit was &lt;a href="http://www.softwarefreedom.org/news/2008/oct/06/busybox-extreme-settle/"&gt;settled&lt;/a&gt; in October 2008. I'm happy to report this because &lt;i&gt;I&lt;/i&gt; imported busybox into the source tree at Extreme, and I really didn't want to get dragged in for depositions. Extreme's engineering management was convinced that waiting until somebody asked for the source code would be fine.&lt;/p&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-8466768608118301038?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=8wOrswnIBlk:oQ4fmDfYSxA:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=8wOrswnIBlk:oQ4fmDfYSxA:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=8wOrswnIBlk:oQ4fmDfYSxA:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=8wOrswnIBlk:oQ4fmDfYSxA:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=8wOrswnIBlk:oQ4fmDfYSxA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=8wOrswnIBlk:oQ4fmDfYSxA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=8wOrswnIBlk:oQ4fmDfYSxA:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=8wOrswnIBlk:oQ4fmDfYSxA:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/8wOrswnIBlk" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=8466768608118301038" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8466768608118301038?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/8466768608118301038?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/08/blog8112009-devrandom.html" title="blog.8.11.2009 &lt; /dev/random" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkMDQnk7eyp7ImA9WxJaFUQ.&quot;"><id>tag:blogger.com,1999:blog-9151880169490356401.post-1262988580427182543</id><published>2009-08-06T13:27:00.000-07:00</published><updated>2009-08-06T13:27:53.703-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-06T13:27:53.703-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Toward a More Robust Twitter Infrastructure</title><content type="html">&lt;p&gt;This morning's &lt;a href="http://twitter.com/"&gt;twitter&lt;/a&gt; outage due to &lt;a href="http://status.twitter.com/post/157191978/ongoing-denial-of-service-attack"&gt;DDoS attack&lt;/a&gt; reminds me: I wrote a guest post for the most excellent &lt;a href="http://crankypm.com/"&gt;Cranky Product Manager&lt;/a&gt;, concerning how to make twitter more robust. It ran on April 1, 2009.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://crankypm.com/2009/04/guest-post-cranky-engineer-responds-prd/"&gt;The Cranky Engineer Responds to a PRD&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9151880169490356401-1262988580427182543?l=codingrelic.geekhold.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cyXiFo2FA_w:C-OXeNivRMQ:Pt5fc6444Es"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cyXiFo2FA_w:C-OXeNivRMQ:Pt5fc6444Es" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cyXiFo2FA_w:C-OXeNivRMQ:bV-q3IutASs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cyXiFo2FA_w:C-OXeNivRMQ:bV-q3IutASs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cyXiFo2FA_w:C-OXeNivRMQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cyXiFo2FA_w:C-OXeNivRMQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodingRelic?a=cyXiFo2FA_w:C-OXeNivRMQ:yVTNFd3iXtc"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodingRelic?i=cyXiFo2FA_w:C-OXeNivRMQ:yVTNFd3iXtc" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingRelic/~4/cyXiFo2FA_w" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=9151880169490356401&amp;postID=1262988580427182543" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/1262988580427182543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/9151880169490356401/posts/default/1262988580427182543?v=2" /><link rel="alternate" type="text/html" href="http://codingrelic.geekhold.com/2009/08/toward-more-robust-twitter.html" title="Toward a More Robust Twitter Infrastructure" /><author><name>Denton Gentry</name><uri>http://www.blogger.com/profile/11782508603268183191</uri><email>denny@geekhold.com</email><gd:extendedProperty name="OpenSocialUserId" value="05410638791985846968" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
