<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Andreas on Coding</title>
	<atom:link href="http://deplinenoise.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://deplinenoise.wordpress.com</link>
	<description>Thoughts about programming.</description>
	<lastBuildDate>Thu, 16 May 2013 05:47:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='deplinenoise.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Andreas on Coding</title>
		<link>http://deplinenoise.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://deplinenoise.wordpress.com/osd.xml" title="Andreas on Coding" />
	<atom:link rel='hub' href='http://deplinenoise.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Fast mmap()able data structures</title>
		<link>http://deplinenoise.wordpress.com/2013/03/31/fast-mmapable-data-structures/</link>
		<comments>http://deplinenoise.wordpress.com/2013/03/31/fast-mmapable-data-structures/#comments</comments>
		<pubDate>Sun, 31 Mar 2013 20:55:34 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=198</guid>
		<description><![CDATA[For version 2 of my build system Tundra, I&#8217;m using a DAG data structure that is designed to be mapped straight into memory. The idea is to only regenerate this data (which can be huge for a game-sized project) when needed, such as when tinkering with compiler options or adding files to the project. These [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=198&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>For version 2 of my build system Tundra, I&#8217;m using a DAG data structure that is designed to be mapped straight into memory. The idea is to only regenerate this data (which can be huge for a game-sized project) when needed, such as when tinkering with compiler options or adding files to the project. These things happen much more rarely than actually issuing a rebuild. This way a regular build will only need to spend about a millisecond (mmap is fast!) to get the DAG data and start building.</p>
<p>As I was working on this problem I went back and forth on the data representation in my files. A DAG is typically very &#8220;pointery&#8221; &#8211; there are lots of references to strings, dependencies and other things that either need an offset or a pointer because they&#8217;re variable sized and can&#8217;t be stored inline.</p>
<p>I&#8217;d identified two main contenders:</p>
<ol>
<li><span style="line-height:13px;">Use indices for every reference, no pointers.</span></li>
<li>Use pointers where it makes sense.</li>
</ol>
<p>Using indices is great because indices take less space than pointers on 64-bit systems. But they&#8217;re sometimes more cumbersome to work with because there&#8217;s implicit context (the array you&#8217;re indexing into) that must be kept around everywhere. Plus it&#8217;s harder to debug a large complex data structure glued together with indices. Also the &#8220;null reference&#8221; typically becomes -1, and that needs to be explicitly handled everywhere or you&#8217;ve got a memory error.</p>
<p>Using pointers is great because it&#8217;s simple to work with, and works well in the debugger too. But they&#8217;re bigger than indices and must be fixed up after the data structure is mapped into ram (unless you can somehow map it to a fixed address which is brittle and something I wanted to avoid.) This means you need to store an additional block of data telling you where the pointers are so you can fix them up &#8211; and that&#8217;s not free either. The basic way to fix up a pointer is to add the base address of the mmap&#8217;d segment to it, a R-M-W operation on random 8 bytes of RAM, which pretty much means a guaranteed cache miss. If you have 100s of thousands of them, it really stats to show as a bottleneck.</p>
<p>So right now I&#8217;m using a hybrid approach of these two where pointers are encoded as a signed 32-bit integer, giving you the relative offset of the target byte with respect to the pointer itself. Although I&#8217;m usually not a fan of C++ templates, this is one case where they help with type safety and reducing casts/mistakes:</p>
<pre>template &lt;typename T&gt;
class FrozenPtr
{
private:
  int32_t m_Offset;
public:
  const T* Get() const
  {
    uintptr_t base = (uintptr_t) this;
    uintptr_t target = base + m_Offset;
    uintptr_t null_mask = (0 == m_Offset) ? 0 : ~uintptr_t(0);
    return reinterpret_cast&lt;T*&gt;(target &amp; null_mask);
  }
  operator const T* () const { return Get(); }

  // ... other stuff, disabling ctors/dtors and so on
};</pre>
<p>The magic happens inside the Get() member function &#8211; we take the address of the pointer itself and add the relative offset in bytes to it. We then mask to see if the offset is zero (that&#8217;s how null pointers are encoded) and return the pointer.</p>
<p>This gives us two nice advantages: pointers are only 4 bytes, and you don&#8217;t need to fix them up. They are however not debugger-friendly and there&#8217;s is a slight cost to dereferencing them. For my use case, it was a pretty good tradeoff. With this pointer template I just mmap the data for my DAG file and immediately cast it to the top-level struct type I care about.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/198/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=198&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2013/03/31/fast-mmapable-data-structures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Loading from Imperfect Data (GDC 2013)</title>
		<link>http://deplinenoise.wordpress.com/2013/03/29/loading-from-imperfect-data-gdc-2013/</link>
		<comments>http://deplinenoise.wordpress.com/2013/03/29/loading-from-imperfect-data-gdc-2013/#comments</comments>
		<pubDate>Fri, 29 Mar 2013 17:38:48 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=191</guid>
		<description><![CDATA[Here are my slides (with notes) from my talk &#8220;Loading from Imperfect Data&#8221; which I gave at GDC 2013. Send any feedback my way! Download slides here (PDF)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=191&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Here are my slides (with notes) from my talk &#8220;Loading from Imperfect Data&#8221; which I gave at GDC 2013.</p>
<p>Send any feedback my way!</p>
<p><a title="Loading from Imperfect Data" href="https://dl.dropbox.com/u/5396666/LoadingImperfectDataFinal.pdf">Download slides here (PDF)</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/191/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=191&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2013/03/29/loading-from-imperfect-data-gdc-2013/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Tool/library memory management &#8211; You&#8217;re doing it wrong</title>
		<link>http://deplinenoise.wordpress.com/2012/10/20/toollibrary-memory-management-youre-doing-it-wrong/</link>
		<comments>http://deplinenoise.wordpress.com/2012/10/20/toollibrary-memory-management-youre-doing-it-wrong/#comments</comments>
		<pubDate>Sat, 20 Oct 2012 18:32:10 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/2012/10/20/toollibrary-memory-management-youre-doing-it-wrong/</guid>
		<description><![CDATA[Warning: this is something of a rant. Don&#8217;t say I didn&#8217;t warn you. Something that continues to frustrate me is the proliferation of poor memory management decisions in tools and libraries for tools. The default is to allocate every single tiny piece of memory with malloc and then free it later. Case in point: JSON parser libraries. Most of [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=188&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Warning: this is something of a rant. Don&#8217;t say I didn&#8217;t warn you.</em></p>
<p>Something that continues to frustrate me is the proliferation of poor memory management decisions in tools and libraries for tools. The default is to allocate every single tiny piece of memory with malloc and then free it later.</p>
<p>Case in point: JSON parser libraries. Most of them allocate tiny JSON values individually from the C library heap. It makes absolutely no sense. The way most command-line tools work with JSON data is to slurp in a data file, parse it to a JSON structure, process that data and then exit. They typically don&#8217;t sit around holding a pointer to a small fragment of a JSON document, it&#8217;s all managed together. The choice to allocate JSON values on the CRT heap individually is terrible in a scenario like that. What we should do instead is to exploit the higher-level knowledge about the memory usage patterns.</p>
<p>A lot of people are now preparing their rebuttal detailing how fast a general heap manager can be and that we can optimize the allocator &#8212; I call bullshit on all that, and here&#8217;s why.</p>
<p>To prove how much of a difference this makes in practice, I modified the popular json-parser library so I can select at runtime whether to use the CRT heap or a custom page-based linear allocator. The program simply reads a block of JSON data into memory and parses it 50 times, immediately throwing away the parsed data.</p>
<p>You can check out the code here on <a title="github" href="https://github.com/deplinenoise/json-parser/tree/malloc_bench">github</a>.</p>
<p>Here are the results:</p>
<pre>$ time mmtest game.json heap

real 0m1.642s
user 0m1.589s
sys  0m0.051s
$ time mmtest game.json linear

real 0m0.755s
user 0m0.697s
sys  0m0.057s</pre>
<p>The stock version using the CRT heap is 2.2x slower!!</p>
<p>Running with valgrind to trace the heap activity reveals the (only) difference between these runs:</p>
<pre>heap: 7,024,565 allocs, 7,024,205 frees, 337,671,820 bytes allocated
linear: 615 allocs, 255 frees, 420,426,770 bytes allocated</pre>
<p>No wonder it&#8217;s faster! That&#8217;s a LOT of cache misses and pointless branches we&#8217;re sidestepping entirely in the malloc/free functions; more than 7 million calls. Sure, we&#8217;re wasting 90 MB of RAM, but do you really care in a command-line program that does its thing and then quits? If you&#8217;re worried about it, it can be trimmed down easily. I used a block size of 1 MB in my linear allocator for this test. Shrinking it down to 128 kb will still give you almost the same benfit. (The mismatched allocs/frees are from Apple code outside my control, go figure.)</p>
<p>The lesson to take away from this is simple: <strong>Never make memory management decisions at the lowest level of a system. Always allow the user to control the memory management policy on the highest possible level, where its possible to do high-level optimizations safely.</strong></p>
<p>As a bonus C++ bashing, this is why anything based on the STL sucks, as it by definition takes microscopic decicions about where memory comes from and how long it will live. The standard response to MM performance concerns is to &#8221;replace the allocator with a more efficient one&#8221;. This is the wrong answer, as I hope you can clearly see above. The fastest code is the one you never have to run.</p>
<p>Rant over. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/188/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=188&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/10/20/toollibrary-memory-management-youre-doing-it-wrong/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Looking towards Tundra 2.0</title>
		<link>http://deplinenoise.wordpress.com/2012/09/30/looking-towards-tundra-2-0/</link>
		<comments>http://deplinenoise.wordpress.com/2012/09/30/looking-towards-tundra-2-0/#comments</comments>
		<pubDate>Sun, 30 Sep 2012 01:34:21 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[tundra]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=184</guid>
		<description><![CDATA[If you don’t know already, Tundra is an open-source build system I’ve written and have been maintaining for a couple of years now. The source is available on github (https://github.com/deplinenoise/tundra). In maintaining the tool, I’ve learned some lessons and rethought some of my initial design decisions. This post is about how I want to evolve [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=184&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you don’t know already, Tundra is an open-source build system I’ve written and have been maintaining for a couple of years now. The source is available on github (<a href="https://github.com/deplinenoise/tundra">https://github.com/deplinenoise/tundra</a>).</p>
<p>In maintaining the tool, I’ve learned some lessons and rethought some of my initial design decisions. This post is about how I want to evolve the tool with those lessons in mind.</p>
<h1>What has worked well</h1>
<p>Tundra is up to version 1.2 now and is relatively stable. It’s definitely not all bad. The current tool is fast and portable. Its used in a lot of projects by friends and other random people on Twitter (you know who you are!) Specifically, I think the following design decisions have worked out well:</p>
<h2>Multi-threaded build engine in C</h2>
<p>The build engine itself has proven to be robust and relatively bug-free since early on. It does parallel dependency and header scanning, so incremental builds run really quickly. It uses simple memory management techniques (just flat arrays mostly) which has turned out to work really well.</p>
<h2>Using Lua for configuration</h2>
<p>Lua is remarkably fast and flexible. I didn’t expect the front-end to run as quickly as it does, given that it does a ton of string processing and data collection before the actual build engine runs. It will commonly dish out a large DAG for the backend in under 100 ms, which is a great achievement for a interpreted script language that has to hit disk to find file names and other things.</p>
<h2>Hard separation between configuration and building</h2>
<p>The current design emphasizes the two distinct phases in the tool: configuration and building. Once the Lua front-end has produced a DAG, it is no longer part of the runtime. This makes the build faster, as the C side can run unimpeded by script language performance and multi-threading issues.</p>
<h2>Header scanning over implicit tracking</h2>
<p>Some new-wave build tools (tup, ninja) depend on tool-specific options or OS/file system-level hooking to automatically track implicit dependencies. This can be convenient when it is supported, but significantly limits the build tool in what platforms it can run on and what tools you can use with it. Tundra has successfully been able to accommodate quirky Amiga toolsets, cross-compilation scenarios (Tundra itself is cross-compiled!) and other non-mainstream scenarios such as custom assemblers by scanning the file system for #include information and keeping a cache of such discovered dependencies.</p>
<h1>What could be improved</h1>
<p>There are some things I’d really like to fix with version 2.0:</p>
<h2>Cleaning up stale build products in the file system</h2>
<p>Because the DAG is generated fresh every time, the front-end doesn’t generate a complete DAG including all possible configurations and variants. This means a debug build will know nothing of the release build targets. If the build engine knew about all the possible outputs, it could safely deduce that certain output files are now stale and can be deleted. This keeps the file system nice and tidy.</p>
<h2>Targeting the build engine with other types of configuration input</h2>
<p>The build engine doesn’t really care about the Lua configuration, but because the tool is a monolithic executable with a single front-end, it’s awkward to try to use it to build something completely unrelated to code. For example, if you’d like to use the build engine to build game assets, it requires a significant amount of Lua scripting within the existing framework (which is code-oriented) to try to express those build rules. If the build engine could be configured in more ways, it would be more useful.</p>
<h2>IDE integration</h2>
<p>There is some integration with Visual Studio and Xcode in the current tool, but it is relatively limited. It would be cool if the current front-end could be made to generate project files that integrate with these tools more easily.</p>
<h1>The Plan</h1>
<p>Here’s how I’ve been thinking about fixing some of this, while keeping the best features around.</p>
<h2>Completely divorce configuration and build engine</h2>
<p>It would be cool to split the tool in three pieces, analogous to how the gcc compiler driver is really multiple executables:</p>
<ol>
<li>One driver executable (the one you invoke &#8211; <em>tundra.exe</em>). This is a light-weight front-end binary that first launches a configuration executable (if needed, see below) and then kicks the build engine.</li>
<li>One configuration executable (<em>tundra-luafrontend.exe</em>). This is a program that encapsulates the task of reading configuration data and producing a DAG as output.</li>
<li>One build engine executable (<em>tundra-buildengine.exe</em>). This program just reads DAG data from a file and executes the build as fast as possible.</li>
</ol>
<p>This design enables some nice benefits:</p>
<ul>
<li>The front-end binary only needs to run when needed (the build files have changed, glob queries would change results, that sort of thing.) Most builds use an identical input DAG. Therefore the top-level build can just skip running the front-end program entirely and use the cached DAG from the previous run. This will shave of precious milliseconds from every incremental build.</li>
<li>The build engine can be targeted directly using a custom front-end tool. This means you can plug in some other DAG generator to build your game assets or run other build rules that are not easily expressible in the Lua front-end. Maybe you already have existing build system data (Visual Studio projects?) that you want to run on the Tundra back-end.</li>
<li>Maintenance becomes simpler, as changes to the front-end can be tested in isolation without involving the back-end, and vice versa.</li>
</ul>
<h2>Produce complete DAG data &#8211; Clean up file system</h2>
<p>If the build-engine sees complete DAG data (all configurations, variants, platforms and so on) it can clean up the file system state before it starts building. The reason this isn’t done today is performance; we don’t want the Lua front-end to generate 8x as many DAG nodes if we’re only going to build the debug config anyway. With the mandatory caching outlined above, this problem goes away&#8211;the data will only be regenerated when you change the build files anyway.</p>
<h1>Feedback welcome</h1>
<p>What would you like to see in Tundra 2.0? Drop me a line and let me know!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/184/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=184&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/09/30/looking-towards-tundra-2-0/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>The App Store Nightmare</title>
		<link>http://deplinenoise.wordpress.com/2012/08/25/the-app-store-nightmare/</link>
		<comments>http://deplinenoise.wordpress.com/2012/08/25/the-app-store-nightmare/#comments</comments>
		<pubDate>Sat, 25 Aug 2012 17:50:16 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=157</guid>
		<description><![CDATA[Edit: The specific error message I was getting is a bug in the App Store relating to disabling SpotLight on your Mac. Once this was fixed, apps from my Swedish region again started updating on the machine, so it seems Apple Support&#8217;s claim about IP address limitations is bogus. Why would they say there is [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=157&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Edit: The specific error message I was getting is a bug in the App Store relating to disabling SpotLight on your Mac. Once this was fixed, apps from my Swedish region again started updating on the machine, so it seems Apple Support&#8217;s claim about IP address limitations is bogus. Why would they say there is one though?</em></p>
<p>I recently moved from Sweden to the US. Now that my bank is here in the US, I switched my Apple account over to the US region.</p>
<p>Doing so made everything under &#8220;Purchases&#8221; and &#8220;Updates&#8221; disappear in the Mac App Store. After a long frustrating email exchange I was told by the App Store support that apps are tied to a region, so if you have downloaded an app in one region it&#8217;s forever tied to that region. Their message was: You have to keep your account in the Swedish region to receive updates. Note that this applies even to free stuff like Twitter!</p>
<p>So at this point I created another account, to be able to download US apps. Everything was fine for a while, although I would have to sign in and out of both my accounts to get updates going. I was getting updates.</p>
<p>Today however a new problem emerged as I tried to update Xcode (which is on my Swedish account.) It&#8217;s no longer showing in &#8220;Purchases&#8221;, and &#8220;Updates&#8221;. Navigating to the Xcode page however shows an &#8220;Update&#8221; button. Clicking that brings up this ominous dialogue</p>
<p><a href="http://deplinenoise.files.wordpress.com/2012/08/screen-shot-2012-08-25-at-10-36-25-am.png"><img class="size-full wp-image" src="http://deplinenoise.files.wordpress.com/2012/08/screen-shot-2012-08-25-at-10-36-25-am.png?w=408" alt="Image" /></a></p>
<p>Signing in to my US account, I&#8217;m greeted with the same dialog.</p>
<p>Puzzled, I sent an email to the Mac App Store Support explaining I could no longer get updates for my apps, regardless of the account I used. Here&#8217;s the takeaway from that email:</p>
<blockquote><p>Please know that since the app was purchase on your iTunes account in Sweden, you may not be able to update app, now that your IP address is in the US. Content in the iTunes store is country specific. Andreas, for this issue, you may need to call our AppleCare technical support team. A technical Advisor will be able to tell you about Apple&#8217;s complimentary and fee-based support. The technical Advisor can also assist you in determining what option might be most helpful to you in this case.</p></blockquote>
<p>So because I have a US IP address I can no longer update my Swedish apps? I took the advice and called Apple Support. A lady informed me that because I didn&#8217;t have active AppleCare for my Macs there was nothing they could do. She offered me to by a one-time pass for $49 or a three year plan for $249. Paying $49 to help Apple debug their DRM? WTF!</p>
<p>I&#8217;m so pissed off at Apple right now I don&#8217;t know what to do except write it up as a warning to others.</p>
<p>To summarize:</p>
<ul>
<li>If you switch regions, you can no longer update (or even see) your apps in the App Store. This goes even for free apps like Twitter and Xcode. So you need to keep your region set to the one where you purchased the app. But..</li>
<li><del>If you&#8217;re in the US, you can&#8217;t download updates for your non-US apps due to IP address constraints.</del> (This seems possible again now that SpotLight is enabled.)</li>
<li>There&#8217;s no way to migrate an app from one account to another (even for freebies such as Twitter)</li>
<li>There&#8217;s no way to permanently remove an app from an account (to reinstall it on another)</li>
<li>App Store Support can do nothing to help you</li>
<li>Apple Support requires AppleCare to do anything about it (if they can, that&#8217;s unknown)</li>
</ul>
<p>So this leaves me with the following options:</p>
<ol>
<li>Completely nuke my machine, create a new US Apple account and repurchase everything (yeah, right)</li>
<li>Pay $49 to have Apple Support look into the issue</li>
<li>Give up and use Linux (I hear Windows 8 will have a locked-down App store too)</li>
</ol>
<p>If this is any indication of the future of software distribution in general, I think I&#8217;m going to just give up and go into farming. AFAIK there are no DRM or geolocation limitations on farming equipment yet.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/157/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=157&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/08/25/the-app-store-nightmare/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>

		<media:content url="http://deplinenoise.files.wordpress.com/2012/08/screen-shot-2012-08-25-at-10-36-25-am.png?w=408" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>
	</item>
		<item>
		<title>The Register Pressure Twilight Zone</title>
		<link>http://deplinenoise.wordpress.com/2012/05/10/the-register-pressure-twilight-zone/</link>
		<comments>http://deplinenoise.wordpress.com/2012/05/10/the-register-pressure-twilight-zone/#comments</comments>
		<pubDate>Thu, 10 May 2012 04:36:29 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=137</guid>
		<description><![CDATA[At Insomniac Games we&#8217;re currently doing a performance push which means lots of opportunity to look at compiler output. In this post I want to share a story on fighting a particular compiler optimization that was causing me problems. One of my areas has been the decal system which is very heavy on 3d data [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=137&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>At Insomniac Games we&#8217;re currently doing a performance push which means lots of opportunity to look at compiler output. In this post I want to share a story on fighting a particular compiler optimization that was causing me problems.</p>
<p>One of my areas has been the decal system which is very heavy on 3d data processing &#8212; a perfect system for SIMD work. While working on one of the bigger compute loops I noticed something odd about the generated PPC code. All of the actual computation work was being done on the vector unit (as it should!), but there was a lot of stack traffic originating from the integer unit. The compiler was overcommitting integer registers it seemed, in what was essentially a pure-SIMD loop. Puzzled, I dug in and tried to work out what was going on.</p>
<p>Let&#8217;s look at the code. The loop I was working on processes 4 triangles at a time and has a structure like this:</p>
<pre>
Vertex* input = ...;
Vertex* output = ...;
int count = ...;

for (int i = 0; i &lt; count; i += 12)
{
  VecSimd t1a = SimdLoad(&amp;input[0].m_Position);
  VecSimd t1b = SimdLoad(&amp;input[1].m_Position);
  VecSimd t1c = SimdLoad(&amp;input[2].m_Position);
  // ... 9 more loads
  VecSimd n1a = SimdLoad(&amp;input[0].m_Normal);
  VecSimd n1b = SimdLoad(&amp;input[1].m_Normal);
  VecSimd n1c = SimdLoad(&amp;input[2].m_Normal);
  // ... 9 more loads
  
  // (crunching)

  SimdStore(out0, &amp;output[0].m_Position);
  SimdStore(out1, &amp;output[1].m_Position);
  SimdStore(out2, &amp;output[2].m_Position);
  // lots more stores

  // increment input and output pointers
  input += 12;
  output += 12;
}
</pre>
<p>What I found was that the vector loads were all being done from different (integer) registers and they were all being incremented individually by the compiler where I was expecting a single base register and 12 offsets. Because there are so many loads and stores going on, the compiler would run out of registers and start spilling them to the stack, generating load-hit-stores and memory penalties all over the loop!</p>
<p>Mike Day offered the following insight:</p>
<blockquote><p> &#8230; in the case where there’s a sensible number of pointers – small enough not to incur spilling onto the stack – the ‘create n pointers’ approach is sensible for the compiler as long as it follows through by doing all the loads using the indexed addressing form of the load instruction. [...] The benefit is that instead of incrementing n pointers per pass (or one pointer n times), it only needs to increment a single offset by n times the stride, saving n-1 adds.</p></blockquote>
<p>It turns out the optimizers for both our PPC compilers were so keen on using the indexed vector load instruction with a single increment that they would blindly overcommit the integer register pool to achieve that particular instruction selection.</p>
<p>The question then became&#8211;how do we force the optimizer to stop doing it? The optimizer can see that the input and output pointers are being moved consistently by a certain stride and any attempt on my part to use variations in the indexing expressions just ended up generating slightly different variations of the same bad behavior.</p>
<p>So let&#8217;s look at what we&#8217;d want if we were writing the loop ourselves in assembly. In this case a better code generation would be to have a single input register and increment it after each SIMD load, using just one register. The key to accomplish this code generation is in C++ to invalidate the optimizer&#8217;s assumptions about the pointers and strides so it can&#8217;t create an array of independent pointers. But how do we do that? After all, everything here is using linear memory accesses with a stride that&#8217;s well known at compile time, enabling the unwanted optimization.</p>
<p>Time for some trickery! The loop structure I ended up using looks like this:</p>
<pre>
static volatile uintptr_t s_secret_sauce = uintptr_t(ptrdiff_t(-1));
static volatile uint32_t  s_stride       = sizeof(Vertex);

// load our constants in from memory into registers
const uintptr_t secret_sauce             = s_secret_sauce;
const uint32_t  stride                   = s_stride;

Vertex* input = ...;
Vertex* output = ...;
int count = ...;

for (int i = 0; i &lt; count; i += 12)
{
  // establish base pointer for all loads in the loop
  uintptr_t base = (uintptr_t(input) &amp; secret_sauce) +
                   offsetof(Vertex, m_Position);

  // load and bump base pointer with stride
  VecSimd t1a = SimdLoad((void*)base); base += stride;
  VecSimd t1b = SimdLoad((void*)base); base += stride;
  VecSimd t1c = SimdLoad((void*)base); base += stride;

  // ... more loads
 
  // update input pointer for next loop iteration
  input = (Vertex*) base;

  // ... rest of loop  

  // ... stores handled similarily
}
</pre>
<p>There are two key things going on in this code that breaks the optimization pattern:</p>
<li>We&#8217;re loading <i>stride</i> and <i>secret_sauce</i> from memory before the loop, thereby preventing any compile-time knowledge of them.</li>
<p></p>
<li>We&#8217;re breaking any loop-wide analysis of the input and output pointers by masking with a value that is unknown to the optimizer, forcing it to rely on the sequence of statements we&#8217;ve laid out exactly.</li>
<p></p>
<p>This generated the desired instruction selection and removed all stack spills from the loop. In one particular case I was using as a performance test case this saved over 30k instructions over the loop lifetime, a significant chunk of work. It also removed several hundred load-hit-store penalties.</p>
<p>This does generate an additional <i>and</i> instruction which is an artifact of the technique, but compared to the much worse stack spilling code this the way better deal. The <i>and</i> could also be replaced with an <i>add</i> of zero or something similar, but it will just amount to the same 1 or 2-cycle overhead in the end.</p>
<p>This has to have been the first time I&#8217;ve used <i>static volatile</i> variables to improve performance. Hopefully it&#8217;s useful to someone else encountering this behavior!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/137/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/137/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=137&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/05/10/the-register-pressure-twilight-zone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>setjmp + goto = error handling bliss</title>
		<link>http://deplinenoise.wordpress.com/2012/04/21/setjmp-goto-error-handling-bliss/</link>
		<comments>http://deplinenoise.wordpress.com/2012/04/21/setjmp-goto-error-handling-bliss/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 05:27:53 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=128</guid>
		<description><![CDATA[Oh yes, it&#8217;s a post about setjmp. Loved by few, feared by most &#8212; setjmp/longjmp is still the best way to write maintainable error handling code in some programs! Consider a line-based assembler or compiler where we want to deal with each line as it comes in from a file. We don&#8217;t want to stop [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=128&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Oh yes, it&#8217;s a post about setjmp. Loved by few, feared by most &#8212; setjmp/longjmp is still the best way to write maintainable error handling code in some programs!</p>
<p>Consider a line-based assembler or compiler where we want to deal with each line as it comes in from a file. We don&#8217;t want to stop compiling on the first line with an error, but flag errors and keep going. As soon as we find an error in a line, we want to abort processing that line and go on with the next one.</p>
<p>The traditional way to solve this is to put a setjmp handler inside the line loop and be prepared to deal with a line going bad. But calling setjmp is expensive as it moves a lot of data from CPU registers to memory (depending on the architecture of course).</p>
<p>Here&#8217;s an interesting way to structure the input loop instead which gives all the benefits of setjmp/longjmp but only incurs a cost when there is an error:</p>
<pre>
static jmp_buf error_jmp;

static int process_file(FILE* input)
{
	volatile int error_count = 0;
retry:
	if (0 != setjmp(error_jmp)) {
		++error_count;
		goto retry;
	}

	while (NULL != fgets(line_buf, sizeof line_buf, input)) {
		/* process line, calling arbitrary functions */
	}

	return error_count;
}
</pre>
<p>Here&#8217;s how it works. We re-establish the setjmp point at the <i>retry</i> symbol rather than inside the line processing loop where we want to get actual work done. Whenever there is an error, the error handling function calls longjmp and we end up back in the if statement following the setjmp, which bumps the error count and resumes by resetting the jump buffer and then running the line loop again!</p>
<p>To put it all together, here&#8217;s how you could design an error reporting function that terminates the processing of a line and resumes with the next one:</p>
<pre>
static void parse_error(const char *fmt, ...)
{
	char buf[1024];
	va_list args;

	va_start(args, fmt);
	vsnprintf(buf, sizeof buf, fmt, args);
	buf[(sizeof buf)-1] = 0;
	fprintf(stderr, "error: %s\n", buf);
	va_end(args);

	longjmp(error_jmp, 1);
}
</pre>
<p>You can then write pretty complex handlers in vanilla C without worrying about how to get out of a tight spot when you encounter a parse error:</p>
<pre>
	if (!foo_bar(data))
		parse_error("expected foo bar to be true");
</pre>
<p>If you don&#8217;t like the static jmp_buf, that can of course be solved too by passing around more state in your processing code. If you do that, you can keep it on the stack inside the outer function which makes the code thread-safe as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/128/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/128/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=128&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/04/21/setjmp-goto-error-handling-bliss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Hot Runtime Linking</title>
		<link>http://deplinenoise.wordpress.com/2012/02/11/hot-runtime-linking/</link>
		<comments>http://deplinenoise.wordpress.com/2012/02/11/hot-runtime-linking/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 05:37:44 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=122</guid>
		<description><![CDATA[This is an idea I&#8217;ve had for a while. Iteration times for native code are not improving much even though we have lots of CPU horsepower for compilation. The number one offender is link times which are as bad and non-parallelizable as ever. So image that you didn&#8217;t have to wait for linking after changing [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=122&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is an idea I&#8217;ve had for a while. Iteration times for native code are not improving much even though we have lots of CPU horsepower for compilation. The number one offender is link times which are as bad and non-parallelizable as ever.</p>
<p>So image that you didn&#8217;t have to wait for linking after changing one or more C or C++ files. Just recompile the individual object files and the game (or other application with an update loop) will pick up your changes, possibly without even restarting.</p>
<p>I think this could be achieved by replacing the link step with a system composed of two parts:</p>
<ol>
<li>A linker daemon (<em>the host</em>)</li>
<li>A target process that loads code+data over the network from the host and then accepts updates from the daemon (<em>the target</em>)</li>
</ol>
<p>The host process manages the address space of the target process. It keeps the target program&#8217;s object code and data in memory and can resolve relocations internally. When all symbol references are satisfied it will push the required changes to the address space of the target over a socket and tell it where to jump. The target process periodically checks for updates and &#8220;parks&#8221; its execution in a safe point where it can receive these updates.</p>
<p>Imagine a scenario with a program consisting of 100 object files. Here is a chain of events describing a programmer working on changes to a subsystem in a few of those object files:</p>
<ol>
<li>The programmer makes a build (but doesn&#8217;t link the program)</li>
<li>The programmer starts the host, telling it to load all the objects. The host resolves symbols and prepares a memory image of the target program, much like a regular linker would, with the key difference that everything is kept in memory.</li>
<li>The programmer starts the target stub, telling it to connect to the host.</li>
<li>The target stub downloads a complete memory image and starts running a loop, calling the main entry point.</li>
<li>The programmer changes a few source files and recompiles only those files.</li>
<li>The host picks up on the object file changes (maybe through an explicit signal from the programmer)</li>
<li>The host relinks the target image in memory, making sure symbols are resolved.</li>
<li>The host synchronizes with the target to make sure it is safe to rearrange its memory image.</li>
<li>The host garbage collects stale code and data that is no longer referenced, possibly by reaching out and scanning the target process memory to make sure there are no dynamically stored pointers into those blocks in a conservative fashion. If so, a warning is printed and the blocks are retained. They can be released on a full restart of the program.</li>
<li>The host transmits the required changes in code and data to the target&#8217;s memory.</li>
<li>The target resumes calling the main update function.</li>
<li>The target runs the new code. Repeat to step #5</li>
</ol>
<div>This would be a pretty cool workflow setup completely free of link time stalls. When the time comes to prepare a final image, just run the linker as normal.</div>
<div></div>
<div>Here are a few issues that would have to be handled carefully:</div>
<div>
<ul>
<li>Function pointers stored in the target memory would point to old versions of functions if they are updated. While we can scan for them and not remove the old code if it is referenced, it would be confusing to the programmer. The target layer can provide a callback to the user program that lets it adjust function pointers as an opt-in API.</li>
<li>Relocation of code to avoid fragmenting the target memory too much. The host could compact most of the target&#8217;s memory space safely while it is suspended in the safe update point and update all relocations accordingly with a patch list. It would avoid moving functions and data that have pointers (pinning them) like described above.</li>
<li>Certain C++ features like static constructors would not work well without additional support.</li>
</ul>
<div>One way to mitigate all these issues would be to restart the target program every time and treat it more as a network loader than a continuing service, but that would require the user program to restart as well. It would be cooler to have it update in place when there is a periodic update function like all games have. Let me know what you think. Is it worth building? What are some other issues that would have to be addressed?</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=122&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/02/11/hot-runtime-linking/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Python Tip: Regex-based tokenizer</title>
		<link>http://deplinenoise.wordpress.com/2012/01/04/python-tip-regex-based-tokenizer/</link>
		<comments>http://deplinenoise.wordpress.com/2012/01/04/python-tip-regex-based-tokenizer/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 13:45:39 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=117</guid>
		<description><![CDATA[Here&#8217;s a handy way to define a lexical analyzer in Python: import re SCANNER = re.compile(r''' (\s+) &#124; # whitespace (//)[^\n]* &#124; # comments 0[xX]([0-9A-Fa-f]+) &#124; # hexadecimal integer literals (\d+) &#124; # integer literals (&#60;&#60;&#124;&#62;&#62;) &#124; # multi-char punctuation ([][(){}&#60;&#62;=,;:*+-/]) &#124; # punctuation ([A-Za-z_][A-Za-z0-9_]*) &#124; # identifiers """(.*?)""" &#124; # multi-line string literal "((?:[^"\n\\]&#124;\\.)*)" [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=117&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a handy way to define a lexical analyzer in Python:</p>
<pre>import re

SCANNER = re.compile(r'''
  (\s+) |                      # whitespace
  (//)[^\n]* |                 # comments
  0[xX]([0-9A-Fa-f]+) |        # hexadecimal integer literals
  (\d+) |                      # integer literals
  (&lt;&lt;|&gt;&gt;) |                    # multi-char punctuation
  ([][(){}&lt;&gt;=,;:*+-/]) |       # punctuation
  ([A-Za-z_][A-Za-z0-9_]*) |   # identifiers
  """(.*?)""" |                # multi-line string literal
  "((?:[^"\n\\]|\\.)*)" |      # regular string literal
  (.)                          # an error!
''', re.DOTALL | re.VERBOSE)</pre>
<p>If you combine this with a re.finditer() call on your source string like this:</p>
<pre>for match in re.finditer(SCANNER, data):
   space, comment, hexint, integer, mpunct, \
   punct, word, mstringlit, stringlit, badchar = match.groups()
   if space: ...
   if comment: ...
   # ... 
   if badchar: raise FooException...</pre>
<p>With this approach you can easily walk through all the tokens in your input string. The captures in each alternative decide what data you get back. If <em>badchar</em> should ever be set, it means there&#8217;s an unrecognized character in your input.</p>
<p>This is probably not the most efficient way to tokenize an input string, but it is short to type and relatively easy to maintain. The only caveats are:</p>
<ul>
<li>You must explicitly match and allow whitespace</li>
<li>You must list the alternatives in the regex so that the most specific cases are caught first.</li>
<li>You must include the <em>badchar</em> alternative or the regex matcher will silently skip past errors in the input string!</li>
</ul>
<div>You can probably adapt this approach to other programming languages and regex toolkits as well. Leave your thoughts in the comments. Have fun!</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=117&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2012/01/04/python-tip-regex-based-tokenizer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
		<item>
		<title>Thoughts on Go</title>
		<link>http://deplinenoise.wordpress.com/2011/10/26/thoughts-on-go/</link>
		<comments>http://deplinenoise.wordpress.com/2011/10/26/thoughts-on-go/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 00:53:24 +0000</pubDate>
		<dc:creator>deplinenoise</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://deplinenoise.wordpress.com/?p=113</guid>
		<description><![CDATA[So I&#8217;ve spent a day with Go. Here are my thoughts on it so far: Language +1: It seems to allow for much terser code than C. Most code I ported over was around 50% of the size which is interesting. Some things that help Go in this regard are multiple return values and the [&#038;hellip<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=113&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>So I&#8217;ve spent a day with Go. Here are my thoughts on it so far:</p>
<p><strong>Language</strong></p>
<ul>
<li>+1: It seems to allow for much terser code than C. Most code I ported over was around 50% of the size which is interesting. Some things that help Go in this regard are multiple return values and the much greater ability to express &amp; use struct literals. For example, stuff like this feels natural after a while as a shortcut of allocating a Foo structure, filling it in and then returning it. This is typically done over many more lines in C:
<pre>return &amp;Foo{
  Bar: a + someFunc(b),
  Baz: "frob",
}</pre>
</li>
<li>+1: The := operator is great, like C++&#8217;s auto or C#&#8217;s var but even terser. Fantastic that it works for multiple return values as well.</li>
<li>+1: Variable declarations in if statements combined with a test is a great way to keep code short &amp; to the point:
<pre>if foo := someFunction(a, b, c); foo != nil {
  // code to use non-nil foo goes here
}</pre>
</li>
<li>-1: I&#8217;m not a great fan of using the casing of identifiers for controlling privacy, exporting or anything else in fact. While it enforces consistency, it also forces you to edit lots of locations if you want to make public a variable that has previously been private and vice versa. -1 on this.</li>
<li>Just weird: forcing an indentation &amp; layout style is close to Python creepy. I like K&amp;R though, so I&#8217;m fine with the choices they&#8217;ve made. I&#8217;m not sure I want the gofmt program to tabulate my comments and structure fields though.</li>
<li>-1: I always find it lame when there&#8217;s no way to replicate what looks like regular functions or patterns provided by the runtime in the language itself. A good example is the append() function which the documentation clearly states cannot be written in Go, as there are no generic types. The same goes for the map &amp; slice objects which have custom syntax and behave generically, but you can&#8217;t do the same thing with your own stuff. That means someone on the language design team has to add your feature to the language in order for it to happen, which it won&#8217;t.</li>
<li>+1 The defer statement is a nice substitute for RAII, using and other hard-coded solutions. It doesn&#8217;t beat Lisp&#8217;s defmacro though <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>-1 The import mechanism feels clunky with string identifiers that are similar to paths. Are they paths? How do they interact with the compiler&#8217;s search directories? When is &#8220;./foo&#8221; needed? Would have been nice with more explicit control &amp; more search directories.</li>
<li>+1 Proper closures, awesome! Really great to be able to nest functions and refer to enclosing scopes transparently. This removes so much junk for callbacks.</li>
<li>-1 No way I&#8217;ve found to do efficient I/O of binary structures. The encoding/binary package uses reflection and type switching for every field.. Ouch! To get some decent speed it would be nice with something similar to C#&#8217;s fixed and a regular cast. Will probably not happen as the language doesn&#8217;t even have unions.</li>
</ul>
<p><strong>Ecosystem &amp; Implementation</strong></p>
<ul>
<li>-1 The packaging &amp; build mechanisms leave a lot to wish for if you&#8217;re trying to build a program using a set of locally defined packages, say for utilities in a bigger program. The default behavior of the suggested makefiles copies your libraries into the system-global Go root. Who wants to copy a broken in-development library into the system Go install dir, leaving junk files everywhere!? The default Make behavior here should be helpful to Go users, not Go maintainers who should hopefully be in lesser numbers and know how to override the defaults.</li>
<li>-1 Related to above, would have wanted the ability to say &#8220;these three files compile together as a package&#8221; rather than having to be forced to put them in their own directory. This is almost as stupid as Java&#8217;s class/directory path handling. The compiler can totally do it so this is purely a infrastructure thing.</li>
<li>-1 Saying &#8220;Memory allocation is too hard &amp; a waste of time, let&#8217;s use GC, modern GC&#8217;s are great!&#8221; and then shipping a really old, bad stop-the-world GC doesn&#8217;t exactly give me lots of confidence. How will a future threaded GC interact with the memory model? I remember the pains Java went through when JVMs started doing incremental, threaded GC.</li>
<li>+1 Compile times have been great so far. Not much difference from C though, but plenty faster than Mono. (This is on OS X.)</li>
<li>+1 The standard library is surprisingly comprehensive for a language this young.</li>
<li>-1 Only static linking, and even hello world programs are <strong>huge.</strong> Caused by early tech &amp; no dead stripping, but a limitation for sure.</li>
<li>-1 The current thread scheduler is really crude, must use environment variables to specify number of cores.</li>
<li>+1 godoc is nice and seems to work well without lots of boilerplate in the comments.</li>
</ul>
<p>To sum up I guess most of the ecosystem &amp; quality of implementation issues are due to the relative young age of the language. The language itself is pretty nice to code in if you think about it as a cross of C and C#, basically C# without all the class &amp; inheritance nonsense which is refreshing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/deplinenoise.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/deplinenoise.wordpress.com/113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=deplinenoise.wordpress.com&#038;blog=17273392&#038;post=113&#038;subd=deplinenoise&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://deplinenoise.wordpress.com/2011/10/26/thoughts-on-go/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/86250132471ed52996b734d80cb1535c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">deplinenoise</media:title>
		</media:content>
	</item>
	</channel>
</rss>
