<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>Planet Orange and Bronze</title>
	<link>http://planet.orangeandbronze.com</link>
	<language>en</language>
	<description>Planet Orange and Bronze - http://planet.orangeandbronze.com</description>

<item>
	<title>JM Ibanez: Quick Updates</title>
	<guid isPermaLink="false">urn:lj:livejournal.com:atom1:jmibanez:35384</guid>
	<link>http://jmibanez.livejournal.com/35384.html</link>
	<description>&lt;p&gt;Two things:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Work on tool that will be released as open source&lt;/b&gt;. I'm currently finishing up a component that we'll be releasing as open source in the coming week or so, once I get the bits cleaned up and checked in. It's a case of an &quot;itch to scratch&quot;, and I'll be using it for a possible work project.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Another haircut&lt;/b&gt;. I got rid of my long hair today. That is all.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Discuss.&lt;/p&gt;</description>
	<pubDate>Sun, 16 Nov 2008 16:10:49 +0000</pubDate>
</item>
<item>
	<title>Dean Berris: IO Bound Application Redux (with Code Samples)</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-5561314488714982757</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/EfX8Ler7mYc/io-bound-application-redux-with-code.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/vZ5q6VIjObtaRySgwR0kJu5GyVs/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/vZ5q6VIjObtaRySgwR0kJu5GyVs/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the previous article I gave a higher level overview of the recent foray I had into &lt;a href=&quot;http://blog.cplusplus-soup.com/2008/11/leveling-up-on-io-bound-parallel.html&quot;&gt;writing a data-parallel application&lt;/a&gt; that maximizes the parallelism that came with the solution to the problem. Now let me go into some of the details of how I made that happen.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Active Object&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;First, I want to propose a simple framework for creating an active object which relies on &lt;a href=&quot;http://asio.sourceforge.net/&quot;&gt;Boost.Asio&lt;/a&gt;. Below is a code snippet for a template that allows you to use &lt;a href=&quot;http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern&quot;&gt;CRTP&lt;/a&gt; and build a simple &lt;a href=&quot;http://en.wikipedia.org/wiki/Active_Object&quot;&gt;Active Object&lt;/a&gt; implementation:&lt;/p&gt;&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;template &amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; Derived&amp;gt;&lt;br&gt;&lt;/br&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; active {&lt;br&gt;&lt;/br&gt;  &lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;:&lt;br&gt;&lt;/br&gt;    shared_ptr&amp;lt;io_service&amp;gt; queue;&lt;br&gt;&lt;/br&gt;    shared_ptr&amp;lt;io_service::work&amp;gt; sentinel;&lt;br&gt;&lt;/br&gt;    shared_ptr&amp;lt;thread&amp;gt; lifetime_thread;&lt;br&gt;&lt;/br&gt;  &lt;br&gt;&lt;/br&gt;  &lt;span style=&quot;color: #0000ff;&quot;&gt;protected&lt;/span&gt;:&lt;br&gt;&lt;/br&gt;    active()&lt;br&gt;&lt;/br&gt;      : queue(&lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt; io_service()),&lt;br&gt;&lt;/br&gt;        sentinel(&lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt; io_service::work(*queue)),&lt;br&gt;&lt;/br&gt;        lifetime_thread(&lt;br&gt;&lt;/br&gt;          &lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt; thread(&lt;br&gt;&lt;/br&gt;            bind(&amp;amp;io_service::run, queue)&lt;br&gt;&lt;/br&gt;            )&lt;br&gt;&lt;/br&gt;          )&lt;br&gt;&lt;/br&gt;    {&lt;br&gt;&lt;/br&gt;      static_cast&amp;lt;Derived*&amp;gt;(&lt;span style=&quot;color: #0000ff;&quot;&gt;this&lt;/span&gt;)-&amp;gt;init();&lt;br&gt;&lt;/br&gt;    }&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;    ~active() {&lt;br&gt;&lt;/br&gt;      sentinel.reset();&lt;br&gt;&lt;/br&gt;      lifetime_thread-&amp;gt;join();&lt;br&gt;&lt;/br&gt;      static_cast&amp;lt;Derived*&amp;gt;(&lt;span style=&quot;color: #0000ff;&quot;&gt;this&lt;/span&gt;)-&amp;gt;destroy();&lt;br&gt;&lt;/br&gt;    }&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; post(function&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt;()&amp;gt; f) {&lt;br&gt;&lt;/br&gt;      queue-&amp;gt;post(f);&lt;br&gt;&lt;/br&gt;    }&lt;br&gt;&lt;/br&gt;};&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;The rationale for the above implementation is that we should be able to easily create active object implementations that have their own internal command queue and their own thread of execution. Above we rely on &lt;a href=&quot;http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html&quot;&gt;Boost.Thread&lt;/a&gt; (for the threading) and &lt;a href=&quot;http://www.boost.org/doc/libs/1_37_0/doc/html/function.html&quot;&gt;Boost.Function&lt;/a&gt; and &lt;a href=&quot;http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html&quot;&gt;Boost.Bind&lt;/a&gt; for the function object wrapping capabilities.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;So let's say we use the above code to create our simple active hasher. The code to something like that is shown below:&lt;/p&gt;&lt;div&gt;&lt;br&gt;&lt;/br&gt;&lt;div style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   1:&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; hasher : active&amp;lt;hasher&amp;gt; {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   2:&lt;/span&gt;   &lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;:&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   3:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; buckets_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   4:&lt;/span&gt;     vector&amp;lt;shared_ptr&amp;lt;ofstream&amp;gt; &amp;gt; file_buckets;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   5:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt; base_name;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   6:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   7:&lt;/span&gt;     friend &lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; active&amp;lt;hasher&amp;gt;; &lt;span style=&quot;color: #008000;&quot;&gt;// allow private access to base&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   8:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   9:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; init() { &lt;span style=&quot;color: #008000;&quot;&gt;// required by active&amp;lt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  10:&lt;/span&gt;       &lt;span style=&quot;color: #0000ff;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; bucket = 0; bucket &amp;lt; buckets_; ++bucket)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  11:&lt;/span&gt;         file_buckets[bucket].reset(&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  12:&lt;/span&gt;           &lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt; ofstream(&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  13:&lt;/span&gt;             base_name + lexical_cast&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt;&amp;gt;(bucket)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  14:&lt;/span&gt;             )&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  15:&lt;/span&gt;           );&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  16:&lt;/span&gt;     };&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  17:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  18:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; destroy() { &lt;span style=&quot;color: #008000;&quot;&gt;// required by active&amp;lt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  19:&lt;/span&gt;       vector&amp;lt;shared_ptr&amp;lt;ofstream&amp;gt; &amp;gt;().swap(file_buckets);&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  20:&lt;/span&gt;     };&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  21:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  22:&lt;/span&gt;   &lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;:&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  23:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  24:&lt;/span&gt;     hasher(&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; buckets, &lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; &amp;amp; base_name_) : &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  25:&lt;/span&gt;       active&amp;lt;hasher&amp;gt;(),&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  26:&lt;/span&gt;       buckets_(buckets),&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  27:&lt;/span&gt;       file_buckets(buckets_),&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  28:&lt;/span&gt;       base_name(base_name_)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  29:&lt;/span&gt;     { };&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  30:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  31:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;operator&lt;/span&gt;() (shared_ptr&amp;lt;vector&amp;lt;tuple&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; &amp;gt; &amp;gt; chunk) {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  32:&lt;/span&gt;       &lt;span style=&quot;color: #008000;&quot;&gt;// schedule for later&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  33:&lt;/span&gt;       active::post(&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  34:&lt;/span&gt;         bind(&amp;amp;hash_impl, &lt;span style=&quot;color: #0000ff;&quot;&gt;this&lt;/span&gt;, chunk)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  35:&lt;/span&gt;       );&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  36:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  37:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  38:&lt;/span&gt;   &lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;:&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  39:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; hash_impl(shared_ptr&amp;lt;vector&amp;lt;tuple&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; &amp;gt; &amp;gt; chunk) {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  40:&lt;/span&gt;       BOOST_FOREACH(tuple&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; &amp;amp; entry, *chunk) {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  41:&lt;/span&gt;         &lt;span style=&quot;color: #008000;&quot;&gt;// write entry to bucket, code not shown.        &lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  42:&lt;/span&gt;       }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  43:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  44:&lt;/span&gt; };&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;Now we have an active hasher, that does its thing asynchronously on its own thread. When a chunk is encoded into the active hasher through the function operator overload (line 31) all we do is post a bound function `hash_impl` with the provided chunk. We can rest assured that hash_impl can and will be run in the lifetime thread -- currently there is only one lifetime thread so we don't have to worry about synchronization in the implementation of hash_impl.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Chunk Reader&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;What we're now missing really is just the chunk reader. In implementing the Chunk Reader we use the &quot;packaged task&quot; idiom. In code, all we do is provide all the parameters the implementation will need at the constructor -- then the function operator overload when invoked doesn't take any parameters and just does whatever it needs to do given member variables. To make it more concrete, let me show you a simple implementation of the Chunk Reader:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;div&gt;&lt;br&gt;&lt;/br&gt;&lt;div style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   1:&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; chunk_reader {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   2:&lt;/span&gt;   &lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;:&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   3:&lt;/span&gt;     size_t offset_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   4:&lt;/span&gt;     size_t elements_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   5:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt; source_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   6:&lt;/span&gt;     hasher &amp;amp; hash_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   7:&lt;/span&gt;   &lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;:&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   8:&lt;/span&gt;     chunk_reader(&lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; &amp;amp; source,&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;   9:&lt;/span&gt;       size_t offset,&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  10:&lt;/span&gt;       size_t elements,&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  11:&lt;/span&gt;       hasher &amp;amp; hash_;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  12:&lt;/span&gt;       ):&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  13:&lt;/span&gt;       offset_(offset),&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  14:&lt;/span&gt;       elements_(elements),&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  15:&lt;/span&gt;       source_(source)&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  16:&lt;/span&gt;     { }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  17:&lt;/span&gt;  &lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  18:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;operator&lt;/span&gt;() () {&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  19:&lt;/span&gt;       shared_ptr&amp;lt;vector&amp;lt;tuple&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; &amp;gt; &amp;gt; chunk;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  20:&lt;/span&gt;       &lt;span style=&quot;color: #008000;&quot;&gt;// do what needs to be done here&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  21:&lt;/span&gt;       &lt;span style=&quot;color: #008000;&quot;&gt;// which is open the file, seek to&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  22:&lt;/span&gt;       &lt;span style=&quot;color: #008000;&quot;&gt;// offset_, and read the chunk, then:&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  23:&lt;/span&gt;       &lt;span style=&quot;color: #008000;&quot;&gt;// ...&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  24:&lt;/span&gt;       hash_(chunk);&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  25:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #606060;&quot;&gt;  26:&lt;/span&gt; };&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;From here, it's just then a matter of setting up the table. Notice that every instance of a chunk_reader needs a reference to a fully constructed hasher instance (line 11). This enforces that every thread hosting the invocation of the function operator overload implementation (line 18) will be able to invoke the hasher's function operator overload -- and thus enqueue the chunk that was gotten from the file.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Gluing Together&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Now the missing part is really the set-up of how you actually create chunk reader threads that read concurrently from a file that defer the hashing to a single thread -- remember, in the original problem the reading is really what's taking too long (30GB read sequentially won't really be fast, but read concurrently can be very accomplished &quot;quite easily&quot;) while the hashing is very quick. The simplest implementation is shown in the code fragment below:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;hasher hash(buckets, &quot;output-&quot;);&lt;br&gt;&lt;/br&gt;thread_group readers;&lt;br&gt;&lt;/br&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; thread_counter = 0; thread_counter &amp;lt; (processors * 2); ++thread_counter)&lt;br&gt;&lt;/br&gt;  readers.create_thread(&lt;br&gt;&lt;/br&gt;    chunk_reader(&lt;span style=&quot;color: #006080;&quot;&gt;&quot;source_file&quot;&lt;/span&gt;, &lt;br&gt;&lt;/br&gt;      thread_counter * size_of_chunk, &lt;br&gt;&lt;/br&gt;      ( file_size / size_of_chunk ) / (processors * 2)),&lt;br&gt;&lt;/br&gt;      hash&lt;br&gt;&lt;/br&gt;      ) &lt;span style=&quot;color: #008000;&quot;&gt;// packaged task&lt;/span&gt;&lt;br&gt;&lt;/br&gt;    ) &lt;span style=&quot;color: #008000;&quot;&gt;// thread create&lt;/span&gt;&lt;br&gt;&lt;/br&gt;readers.join_all();&lt;br&gt;&lt;/br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;And there we have it. The approach taken here has been reduced to the parts that matter highlighting how we can leverage the available parallelism in a solution by properly decomposing the problem into sub-problems that get solved independent of others.&lt;/p&gt;&lt;p&gt;I hope this sheds more light and gives those reading insights about how you can possibly leverage multi-core architectures by writing code that exploits the concurrency in the solution and the available hardware.&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=x2ROIdH4&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=NxeMVhgq&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=DGtfK9eA&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=b7szKlqM&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=DEr57RKS&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=DEr57RKS&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=kmlVqCJd&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=kmlVqCJd&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=XbZmCX2E&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=6RdzLzAk&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=6RdzLzAk&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=IIiUJ6dq&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/EfX8Ler7mYc&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Sat, 08 Nov 2008 14:11:16 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Leveling Up on IO Bound Parallel Applications</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-4164501741060034068</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/0Flr08K6jRQ/leveling-up-on-io-bound-parallel.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/oKnI7dGB-Ww47tiJh-YuVY4VSwM/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/oKnI7dGB-Ww47tiJh-YuVY4VSwM/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently I had a chance to solve a simple problem which took forever to do with a single process. Here's the problem: I have a ~30GB file with structured binary data (a tuple of ints serialized as-is in memory) and I'm supposed to hash entries according to the first element of each contained tuple into multiple files.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Sounds simple and straightforward in a single-threaded application right? Right.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;The problem then becomes the fact that the act of reading a tuple from disk to memory, deserializing it into memory, and then hashing it into the correct bucket is 90% I/O and 10% processing. Now imagine if you're on a multi-core machine (2 processors with 2 cores each having 2 hardware threads (in short 8 available processors)) and you're essentially using 10% of 1/8 the capacity of the machine. This is hardly satisfactory -- and not to mention painfully slow.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;I then think to myself: this is an embarrassingly parallel problem, which I can solve by simply dividing the file up into a number of chunks, have one thread deal with one chunk of the file, then serialize the access to the files using an active object that maintains the streams that correspond to each &quot;bucket&quot; file. So I use Boost.Aisio's io_service object as a message/command queue for the actual writing/hashing of the tuple and read the file from many different threads to enqueue each tuple one by one. Problem solved.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Apparently not -- using &lt;a href=&quot;http://htop.sourceforge.net/&quot;&gt;htop&lt;/a&gt; I verify that the CPU's are filling up with red all over, and the queue is growing too fast for the active object to handle. This can only mean one thing: the process is more I/O bound than I thought.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;One problem I was encountering was the granularity of each tuple having to be written to the buffer one at a time. The way the lifetime thread in the active object works is that it tries to lock a mutex on the queue -- while producer threads at the same time compete for the lock to add items to the queue -- once the consumer thread does get a tuple, it takes too long to write the tuple and before it knows what's happened it's competing for the lock again. Not only am I hitting an IO limit/cap of the hardware+OS combination, I was also introducing too much contention on the queue.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;After pondering about it a little more, I thought to myself: why don't I batch up the tuples into a shared container that's in the heap and enqueue that chunk instead? That way the thread will maximize the IO time allotted to it and building the container instead of trying to compete for a lock all the time.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;This little trick works -- by making the task running in the thread spend more time as much useful work as possible (reading the contents of the file and building the container) rather than making it compete all the time with other threads for a lock on the queue mutex, we maximize &quot;productive&quot; time and lessen &quot;contention&quot; time. This spells good performance and better hardware utilization.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;So I thought running one thread per available hardware thread was going to do the trick -- apparently, I was wrong. Remember that the tasks were 90% IO and 10% &quot;productive&quot; work? This meant the threads kept waiting on IO rather than doing any/much useful work. More than half the time the threads were idling waiting for something to happen.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;The solution seems to be to leverage the fact that IO waiting times dominate the computation. Running more threads per processor enables the OS to context switch away from a thread that's waiting for IO and move to a thread that is ready to process data. So if we have two threads with 9:1 IO to CPU work ratio sharing one hardware thread, we get 100% improvement on CPU utilization, and 50% reduction on waiting time -- of course we don't want to overdo it because it will introduce unnecessary overhead for too much context switching.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;These series of optimizations allowed me to go from ~3 hours of processing a 30GB file (using a PERL script that did the hashing) down to ~1 hour of processing(with the 1:1 thread:processor ratio) down to ~30 minutes (with the 2:1 thread:processor ratio).&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;In the next post, I will dissect the code to reveal how I was able to achieve this kind of speedup on IO Bound applications.&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=1bFsxNjE&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=D93I7RZB&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=dTGvMgx0&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=J5jcFYms&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ZwFIR34T&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ZwFIR34T&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ELGHXaQW&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ELGHXaQW&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=6b3qGPdb&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=81GU6wQk&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=81GU6wQk&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=VGRvrUUk&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/0Flr08K6jRQ&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Wed, 05 Nov 2008 13:21:32 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: How about Meta-DSELs?</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-1269711288028563324</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/5idQixlTzi8/how-about-meta-dsels.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/jmnYalGSN60elHBRcfwOeocxFWY/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/jmnYalGSN60elHBRcfwOeocxFWY/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;With the recent &lt;a href=&quot;http://www.boost.org/users/news/version_1_37_0&quot;&gt;release of Boost 1.37.0&lt;/a&gt;, the Boost C++ library now contains a Domain Specific Embedded Language (DSEL) framework in the form of &lt;a href=&quot;http://www.boost.org/doc/libs/1_37_0/doc/html/proto.html&quot;&gt;Boost.Proto&lt;/a&gt;. No, this is &lt;strong&gt;NOT&lt;/strong&gt; another library that just uses template metaprogramming tricks to do something really cool (like &lt;a href=&quot;http://spirit.sourceforge.net/&quot;&gt;Boost.Spirit&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Imagine being able to create your own mini-language from within C++? Introducing Boost.Proto -- a DSEL for building your own DSEL. From the Boost.Proto documentation:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Proto is a framework for building Domain Specific Embedded Languages in C++. It provides tools for constructing, type-checking, transforming and executing &lt;em&gt;expression templates&lt;/em&gt; &lt;sup&gt;[&lt;a href=&quot;http://www.boost.org/#ftn.id3473038&quot; name=&quot;id3473038&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt; . More specifically, Proto provides: &lt;/p&gt;&lt;ul&gt; &lt;li&gt;An expression tree data structure.  &lt;/li&gt;&lt;li&gt;A mechanism for giving expressions additional behaviors and members.  &lt;/li&gt;&lt;li&gt;Operator overloads for building the tree from an expression.  &lt;/li&gt;&lt;li&gt;Utilities for defining the grammar to which an expression must conform.  &lt;/li&gt;&lt;li&gt;An extensible mechanism for immediately executing an expression template.  &lt;/li&gt;&lt;li&gt;An extensible set of tree transformations to apply to expression trees.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt; &lt;p&gt;There is something really weird with this library -- its intention is to allow practically anybody to create their own mini-language from within C++. It's no surprise that the Boost.Spirit library (and Boost.Phoenix library) will be using it in the next versions.&lt;/p&gt; &lt;p&gt;Not only is building DSELs in C++ possible, it's now made more accessible. So if you've always wanted to try building your own domain specific embedded language in C++, now is the time to start flexing those brain muscles and reading up on Boost.Proto.&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=8hUmbUVv&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=mdZUCbfT&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=8LWz1joR&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=buKd4QgG&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=X5y8EABg&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=X5y8EABg&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=cU2kM0bv&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=cU2kM0bv&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=mXhCwMVP&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ffoMQnAx&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ffoMQnAx&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=vUtg7zQB&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/5idQixlTzi8&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Tue, 04 Nov 2008 14:53:18 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Boost C++ Library Patches (1.36.0)</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-4333468960602034905</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/D0NNP_CJnGA/boost-c-library-patches-1360.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/3sf2lJvOt3gtVNE94vMJ5lm3Wmg/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/3sf2lJvOt3gtVNE94vMJ5lm3Wmg/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;For those who have been having some trouble getting some libraries to compile nicely in Boost 1.36 using GCC 4.3.2, I have posted some issues (and associatively some patches) to &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/doc/html/date_time.html&quot;&gt;Boost.Date_Time&lt;/a&gt;, &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio.html&quot;&gt;Boost.Asio&lt;/a&gt;, and &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/libs/system/doc/index.html&quot;&gt;Boost.System&lt;/a&gt; to the &lt;a href=&quot;https://svn.boost.org/trac/boost/&quot;&gt;Boost Trac installation&lt;/a&gt;. I've listed them down here with a short description of what the issue is and what the solution is (and where you can get the patch for Boost 1.36.0).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;GCC 4.3.2 and stricter identifier restrictions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In the past versions of GCC, the following code would pose no problems:&lt;/p&gt; &lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;namespace&lt;/span&gt; ns {&lt;br&gt;&lt;/br&gt;    template &amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; T&amp;gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; name {&lt;br&gt;&lt;/br&gt;    };&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;    name&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; name; // error here!&lt;br&gt;&lt;/br&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now however, you'll get an error saying &quot;declaration of 'name' changes the meaning of identifier 'name'&quot;. Apparently the fix is trivial which is to give the namespace qualified name:&lt;/p&gt;&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;namespace&lt;/span&gt; ns {&lt;br&gt;&lt;/br&gt;    template &amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; T&amp;gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #0000ff;&quot;&gt;struct&lt;/span&gt; name {&lt;br&gt;&lt;/br&gt;    };&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;    ns::name&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; name; &lt;span style=&quot;color: #008000;&quot;&gt;// no error anymore&lt;/span&gt;&lt;br&gt;&lt;/br&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is some code in Boost.Date_Time (release 1.36.0) which has this problem. The issue is reported as Boost Trac issue &lt;a href=&quot;https://svn.boost.org/trac/boost/ticket/2465&quot;&gt;#2465&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GCC 4.3.2 and stricter member construction requirements&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Apparently GCC 4.3.2 has a more strict requirement on when a particular member variable is actually initialized or not -- especially when they are used as temporaries in a static function. I'm not sure if this is a compiler bug/feature, but nonetheless Boost.Date_Time's contrained_value template does not explicitly initialize the member 'value_' variable.&lt;/p&gt;&lt;p&gt;The trivial fix (which is to default-construct the member variable in the constructor) is available attached to issue &lt;a href=&quot;https://svn.boost.org/trac/boost/ticket/2463&quot;&gt;#2463&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Boost.System's Missing 'get_posix_category'&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In Boost 1.36.0, Boost.System's get_posix_category function had been removed. For strict backwards compatibility, it has to be put in to let older versions of libraries that use the function to link properly. This has been submitted as issue (with patches attached)  &lt;a href=&quot;https://svn.boost.org/trac/boost/ticket/2461&quot;&gt;#2461&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Boost.Asio's 'pipe_select_interrupter' warning&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Still with GCC 4.3.2, discarded return values turn out to be warned against. There is a function in Boost.Asio's detail implementations that calls '::write(...)' and then ignores the return value -- which throws a warning and causes builds with -Werror to fail. The trivial patch is attached to the submitted issue &lt;a href=&quot;https://svn.boost.org/trac/boost/ticket/2462&quot;&gt;#2462&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Caveats&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;These patches are submitted to the Boost community through the Trac Issue Trackings system. They have not yet been accepted by authors/maintainers at the time of this writing. Like the saying goes, use at your own risk.&lt;/p&gt;&lt;p&gt;Just as a reminder, these patches are to be applied to the Boost 1.36.0 release -- Boost 1.37.0 may have some of these issues addressed. If you find have questions about the patches (and don't want to post comments to the blog entry) please contact me directly through &lt;a href=&quot;mailto:dean.berris@cplusplus-soup.com&quot;&gt;dean.berris@cplusplus-soup.com&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=1iK68mYr&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=deVxC4WT&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=k6K3Z0Ww&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=VMgYUZYl&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=dm6AQ5bK&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=dm6AQ5bK&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ixuphn9m&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ixuphn9m&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=bHfC8Qb0&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=yvI0U62y&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=yvI0U62y&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=SfOOsuV2&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/D0NNP_CJnGA&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Mon, 03 Nov 2008 13:32:40 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Sea Change in Parallel Programming</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-7966213343016426979</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/HC--bbIsn_E/sea-change-in-parallel-programming.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/yEG9gvy2iu_5wOiejPE6Chynz1Q/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/yEG9gvy2iu_5wOiejPE6Chynz1Q/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;While going through my reading list, I found a very interesting entry about &quot;&lt;a href=&quot;http://www.codeguru.com/cpp/w-p/system/threading/article.php/c15649__1/&quot;&gt;Parallel Programming with Visual C++ 2010 CTP&lt;/a&gt;&quot; by &lt;a href=&quot;http://www.codeguru.com/member.php/124583/&quot;&gt;Marc Gregoire&lt;/a&gt;. Quoting the introduction:  &lt;/p&gt;&lt;blockquote&gt;The CTP build of Visual C++ 2010 includes a new library to help you write native parallel code. Writing parallel code is getting more and more important with the broad availability of quad-core CPUs at this time and the many-core CPUs that will appear in the coming years. I will only be talking about the new concurrency library for native code. Of course, writing parallel code has already been possible for a long time. However, you had to create and manage all threads by yourself and this could often be a complex task. Because of this, it requires quite a bit of time to parallelize a simple loop over multiple threads. The new native concurrency library makes this much easier.&lt;/blockquote&gt; &lt;p&gt;&lt;br&gt;&lt;/br&gt;Off the top of my head, I think this is a major development as far as C++ and parallel computing go. Bringing the tools and techniques (as well as idioms and patterns) of parallel computing closer to the developers allows for the start of the sea change in the way people approach programming in general. However, I would have to mention something that is subtly different in the way people approach parallelism now and for the foreseeable future.&lt;/p&gt; &lt;p&gt;Currently when you think about parallel computing/programming in C++ it usually includes the notion of threads and synchronization of access to data structures. If you come from a strictly imperative programming background this results in step-by-step changing of state and protecting memory from being changed in the wrong order. If you come from a functional programming background you'll have to think about how to decompose the solution into parts that result into something (or sends a message to something else) and reducing the result of these (potentially parallel-executed) tasks in the end.&lt;/p&gt; &lt;p&gt;The change in paradigm has something to do with the melding of these two approaches to parallel computing to yield a hybrid approach. Good thing with C++0x is that it's now easier to go a little functional while staying imperative in places that matter. To illustrate this, I'll post some C++0x code using &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio.html&quot;&gt;Boost.Asio&lt;/a&gt; and &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/doc/html/thread.html&quot;&gt;Boost.Thread&lt;/a&gt; to show what I mean:&lt;/p&gt; &lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;p&gt;vector&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt; sums;&lt;br&gt;&lt;/br&gt;vector&amp;lt;vector&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;gt; all_numbers; &lt;span style=&quot;color: #008000;&quot;&gt;// initialized with contents...&lt;/span&gt;&lt;br&gt;&lt;/br&gt;mutex sums_mutex;&lt;br&gt;&lt;/br&gt;io_service queue;&lt;br&gt;&lt;/br&gt;shared_ptr&amp;lt;io_service::work&amp;gt; sentinel(new io_service::work(queue));&lt;br&gt;&lt;/br&gt;thread_group threads;&lt;br&gt;&lt;/br&gt;for (unsigned i=0u; i &amp;lt; processors; ++i)&lt;br&gt;&lt;/br&gt;    threads.create_thread(&lt;br&gt;&lt;/br&gt;        [&amp;amp;queue]() { queue.run(); }&lt;br&gt;&lt;/br&gt;        );&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;for_each(all_numbers.begin(), all_numbers.end(),&lt;br&gt;&lt;/br&gt;    [&amp;amp;sums, &amp;amp;queue, &amp;amp;sums_mutex](vector&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;&amp;gt;&amp;amp; numbers) {&lt;br&gt;&lt;/br&gt;        queue.post(&lt;br&gt;&lt;/br&gt;            [&amp;amp;numbers, &amp;amp;sums_mutex]() {&lt;br&gt;&lt;/br&gt;                &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; sum = accumulate(numbers.begin(), numbers.end(), 0);&lt;br&gt;&lt;/br&gt;                scoped_lock &lt;span style=&quot;color: #0000ff;&quot;&gt;lock&lt;/span&gt;(sums_mutex);&lt;br&gt;&lt;/br&gt;                sums.push_back(sum);&lt;br&gt;&lt;/br&gt;            });&lt;br&gt;&lt;/br&gt;    });&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/br&gt;sentinel.reset();&lt;br&gt;&lt;/br&gt;threads.join_all();&lt;br&gt;&lt;/br&gt;&lt;/p&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;div&gt; &lt;/div&gt;&lt;p&gt;Here we are mixing the use of mutexes (an inherently threading-specific construct) with lambdas (a functional programming idiom) to produce a highly concurrent way of computing the sums of a vector of vectors. What we're seeing here is a self-load balancing solution that makes each thread as busy as possible while only synchronizing on the modification of the sums vector.&lt;/p&gt;&lt;p&gt;One other thing to note here is that there are emerging patterns of parallelism in &quot;chunked&quot; or &quot;task-based&quot; concurrency:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none;&quot;&gt;&lt;p&gt;function parallelized_computation(...) {&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #008000;&quot;&gt;// Initialize data structures&lt;/span&gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #008000;&quot;&gt;// Set up the worker pool&lt;/span&gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #008000;&quot;&gt;// Schedule computations&lt;/span&gt;&lt;br&gt;&lt;/br&gt;    &lt;span style=&quot;color: #008000;&quot;&gt;// Wait on worker pool to complete&lt;/span&gt;&lt;br&gt;&lt;/br&gt;};&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;So while there are many models to concurrent/parallel computing, the basic building block is decomposition of the computation into units that can happen simultaneously. The details though, is where the complexity usually lies.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/&quot;&gt;Microsoft&lt;/a&gt; has decided to deal with concurrent/parallel computing with the Parallel Pattern Library among other concurrent programming goodies that's already available in the &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en&quot;&gt;Micrsoft Visual C++ 2010 Community Technology Preview (CTP)&lt;/a&gt;. A good thing with this approach is that it plays very well with the next version of the upcoming C++0x standard (&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2135.pdf&quot;&gt;which is now in working draft form&lt;/a&gt;, so that means there won't be much changing between now and when the standard gets ratified).&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;http://gcc.gnu.org/&quot;&gt;GNU Compiler Collection&lt;/a&gt; deals with parallelism at a lower level with &lt;a href=&quot;http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html&quot;&gt;parallel versions of the STL algorithms&lt;/a&gt; with OpenMP annotations in the implementation level. This spells good news to those who want to play with an open source version without needing additional infrastructure to leverage parallelism for applications. GCC 4.3.2 also already has &lt;a href=&quot;http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x&quot;&gt;partial support for C++0x features&lt;/a&gt; (which can be enabled by the -std=c++0x compiler flag).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://intel.com/&quot;&gt;Intel&lt;/a&gt; already has the &lt;a href=&quot;http://www.intel.com/cd/software/products/asmo-na/eng/294797.htm&quot;&gt;Threading Building Blocks library&lt;/a&gt; (&lt;a href=&quot;http://www.threadingbuildingblocks.org/&quot;&gt;also open source&lt;/a&gt;) which provides lots of useful multi-threaded programming constructs for current compilers. I personally am not sure whether the &lt;a href=&quot;http://www.intel.com/cd/software/products/asmo-na/eng/compilers/284132.htm&quot;&gt;Intel C++ compiler&lt;/a&gt; already has support for C++0x but I am not going to be surprised if they're already near getting a release out that does support newer language features.&lt;/p&gt;&lt;p&gt;Getting back into the topic of the sea change, it almost seems to be inevitable that parallel computing will play a major role in the further evolution of both the C++ programming language as well as application development in general. There is definitely a lot of interest in building better tools and better toolkits not only from the customer standpoint (people want programs they use to get faster as they buy better hardware to run it on) but also the developer standpoint (not using 100% CPU to get the job done faster almost always seems to be one of the best occupations out there).&lt;/p&gt;&lt;p&gt;And from where I'm looking, it seems like the future ahead is definitely bright.&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=d5DXmv96&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Vbkd1u3d&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=QEjcoVyX&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=gxBFUnDi&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=RtLuWNIq&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=RtLuWNIq&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=MajvlwaU&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=MajvlwaU&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=RdueGCnO&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=g7PNcbve&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=g7PNcbve&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=rdGaA7Rs&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/HC--bbIsn_E&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Sat, 01 Nov 2008 16:55:06 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Cache Friendliness and Concurrency</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-8902955475083210148</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/g4UVUHsyBqk/cache-friendliness-and-concurrency.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/FF-cOjBsQEYoWQT6_3kDStmREl8/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/FF-cOjBsQEYoWQT6_3kDStmREl8/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href=&quot;http://herbsutter.wordpress.com/&quot;&gt;Herb Sutter&lt;/a&gt; had his article about addressing &quot;the general problem of supporting multiple producers and multiple consumers with as much concurrency as possible.&quot; at Dr. Dobb's Journal earlier and I find a few things really interesting with the approach he's taken to leverage concurrency more by playing nicely with the cache. I quote:&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;blockquote&gt;Fourth, we want to follow the advice that &quot;if variables A and B are not protected by the same mutex and are liable to be used by two different threads, keep them on separate cache lines&quot; to avoid false sharing or &quot;ping-ponging&quot; which limits scalability. [3] In this case, we want to add padding to ensure that different nodes (notably the first and last nodes), the first and last pointers into the list, and the producerLock and consumerLock variables are all on different cache lines.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;from &lt;a href=&quot;http://www.ddj.com/cpp/211601363?pgno=1&quot;&gt;October 29, 2008 - Writing a Generalized Concurrent Queue&lt;/a&gt;&lt;br&gt;&lt;/br&gt;[3] refers to H. Sutter. &quot;Maximize Locality, Minimize Contention&quot; (DDJ, September 2008). Available online at &lt;a href=&quot;http://ddj.com/architect/208200273&quot;&gt;http://ddj.com/architect/208200273&lt;/a&gt;.&lt;br&gt;&lt;/br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;What's interesting here is that in code, it looks a little funny (&lt;a href=&quot;http://www.ddj.com/cpp/211601363?pgno=2&quot;&gt;still from the same article&lt;/a&gt;):&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br&gt;&lt;/br&gt;template &amp;lt;typename T&amp;gt;&lt;br&gt;&lt;/br&gt;struct LowLockQueue {&lt;br&gt;&lt;/br&gt;private:&lt;br&gt;&lt;/br&gt;  struct Node {&lt;br&gt;&lt;/br&gt;    Node( T* val ) : value(val), next(nullptr) { }&lt;br&gt;&lt;/br&gt;    T* value;&lt;br&gt;&lt;/br&gt;    atomic&amp;lt;Node*&amp;gt; next;&lt;br&gt;&lt;/br&gt;    char pad[CACHE_LINE_SIZE - sizeof(T*)- sizeof(atomic&amp;lt;Node*&amp;gt;)];&lt;br&gt;&lt;/br&gt;  };&lt;br&gt;&lt;/br&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;So aside from being a little wasteful all in all this code seems to make use more of the hardware capabilities and in turn makes it a very platform-specific approach. It would be nice to have a general utility -- perhaps a macro -- that's implemented to provide padding on a per-compiler/platform basis.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;All in all the article is a good read and thinking about extracting as much concurrency and as little synchronization has possible makes me think should there be new idioms developed when concurrency-centric programming comes to C++? I'm guessing the future sure is looking very bright for C++ and parallel/concurrent computing and programming in general.&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=J2U8QHZM&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=DBbrIpBt&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=2CBUTYIy&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=2AtqpIP6&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ObP78wjr&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ObP78wjr&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=oVPsiXHk&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=oVPsiXHk&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=dFxNSWG2&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=IYAbhg73&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=IYAbhg73&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Ta3Q0yAm&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/g4UVUHsyBqk&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Fri, 31 Oct 2008 08:45:49 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Parallel Computing on the Desktop</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-8370397769135801767</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/tmMGFGQ3oNY/parallel-computing-on-desktop.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/4e-JdVCBn7N7yHa1G4BIvPXxAh4/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/4e-JdVCBn7N7yHa1G4BIvPXxAh4/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I was reading through my reading list and I stumbled upon this post by &lt;a href=&quot;http://software.intel.com/en-us/blogs/author/james-reinders/&quot;&gt;James Reinders (Intel)&lt;/a&gt; titled &quot;&lt;a href=&quot;http://software.intel.com/en-us/blogs/2008/10/29/on-processors-cores-and-hardware-threads/&quot;&gt;on Processors, Cores and Hardware threads&lt;/a&gt;&quot;:&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;blockquote&gt;Imagine a system with two processors, each eight core, and two hardware threads. Such a machine will offer 32 hardware threads.&lt;/blockquote&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Now that's not hard to imagine on the server side -- but even though it sounds like a lot of hardware threads, the sad reality is that applications written today aren't designed specifically to work on more than one hardware thread. Considering that operating systems already leverage the available parallelism in these systems (allowing users to interact with many different applications possibly doing things in the background at the same time) &quot;out of the box&quot;, it's a different thing for developing your own custom software solution. And this is even on the server side.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Now a desktop that has that many number of hardware threads available means we have to look at different ways of writing applications that will scale as the number of hardware threads increase (even if each hardware thread doesn't execute as fast as single processors do a couple of years ago maybe). That means it's no longer just alright for your game, spreadsheet application, word processor, image/video editing software, or integrated development environment to just run on a single thread and not take advantage of available hardware threads -- or the OS should be a little smarter in distributing which software thread gets mapped to which hardware thread.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;More than ever knowledge in parallel computing idioms and multi-threading techniques and designs would be valuable -- and soon necessary. I just hope people will get caught up in the wave and start swimming sooner than later.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;And I think it's more true now that &quot;scaling&quot; is the name of the game.&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=eqUkMxLN&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=mCWT7RCN&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=YgaeTWpr&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=6dIZ5QYe&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=mQxkYepe&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=mQxkYepe&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ou4YsbNN&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=ou4YsbNN&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Hpz5Vj8T&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=XOZsVRfq&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=XOZsVRfq&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=E6PhbcZC&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/tmMGFGQ3oNY&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Thu, 30 Oct 2008 07:38:13 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Trying out New Layout</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-4004256172050760881</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/TcGaOCftWFg/trying-out-new-layout.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/V_si4LD8VUbCJ84sVv_nMPyC5UU/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/V_si4LD8VUbCJ84sVv_nMPyC5UU/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I've decided to spice things up a little on the site by changing the theme to a more eye-friendly (I think) color scheme. The previous layout made the site a little too plain and clean cut with very little variation. Now I'm trying something out to help with the look and readability (I hope) of the new layout.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Let me know if you like the color scheme or whether you like the older layout/theme better. If you're reading the feed, I'm pretty sure the content shouldn't be too much affected as you read through your favorite RSS reader.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;At any rate, drop by the site and let me know what you think about the new theme!&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Kmy9ETLJ&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=PNCds2Jn&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=I9WLEwNq&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=OZMIggTU&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=kQUKmbyb&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=kQUKmbyb&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=4UkR9dYY&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=4UkR9dYY&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=NseHX9La&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=mK6hiUM9&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=mK6hiUM9&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=ZgHuoYIS&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/TcGaOCftWFg&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Wed, 29 Oct 2008 13:52:41 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Dean Berris: Coarse-Grained Data-Parallel: Statistics</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-12142884.post-7935238380608367391</guid>
	<link>http://feedproxy.google.com/~r/CppSoup/~3/K7f2dHU4Mqs/coarse-grained-data-parallel-statistics.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://feedads.googleadservices.com/~a/N9chQj-u-LqToilVK1ndQLIjrtM/a&quot;&gt;&lt;img src=&quot;http://feedads.googleadservices.com/~a/N9chQj-u-LqToilVK1ndQLIjrtM/i&quot; border=&quot;0&quot; ismap=&quot;true&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This field of data-parallel programming/computation is a very active one, since apparently it's a very important one as well for a few reasons. These reasons are not trivial and by no means unique to the field. Some of these reasons are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Much of business and research activities rely on timely and accurate results.  &lt;/li&gt;&lt;li&gt;Results usually matter at scale -- the more data you have, the better results you usually get.  &lt;/li&gt;&lt;li&gt;The more data you have to deal with, usually you have a pretty hard problem to solve.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;These three reasons above are the basic driving forces for looking into higher performance solutions to considerably large problems. Having said this, when you have the combination of large amounts of data and the requirement for timely and accurate results, you usually look at being able to leverage what's available to the maximum. With the advent then of multi-core computers, you try and leverage the parallelism available with being able to use more than one processor to do a lot of things at virtually the same time.&lt;/p&gt; &lt;p&gt;Intel has the Summary Statistics Library which (according to &lt;a href=&quot;http://softwarecommunity.intel.com/articles/eng/3830.htm&quot;&gt;this article&lt;/a&gt;):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Intel® Summary Statistics Library is a set of algorithms for parallel processing of multi-dimensional datasets. It contains functions for initial analysis of raw data which allow investigating structure of datasets and get their basic characteristics, estimates, and internal dependencies.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The potential problems with this solution are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Proprietary license for the &lt;a href=&quot;http://www.intel.com/cd/software/products/asmo-na/eng/307757.htm&quot;&gt;Intel Math Kernel Library&lt;/a&gt;.  &lt;/li&gt;&lt;li&gt;Tuned for Intel machines using Intel compilers.  &lt;/li&gt;&lt;li&gt;Close-sourced, hard to identify accuracy of implementation.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Another possible solution is to use the &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/doc/html/accumulators.html&quot;&gt;Boost.Accumulators&lt;/a&gt; framework. According to the documentation:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Boost.Accumulators is both a library for incremental statistical computation as well as an extensible framework for incremental calculation in general. The library deals primarily with the concept of an accumulator, which is a primitive computational entity that accepts data one sample at a time and maintains some internal state.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Given this, the problems with this when you want to do parallel computations are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Each accumulator works in an incremental fashion -- deal with data points one at a time.  &lt;/li&gt;&lt;li&gt;It's hard to parallelize because each accumulator maintains state that depends on a previous state.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Possible Approaches&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There are two possible approaches to developing a data-parallel statistics implementation. Let's consider a simple problem: computing the mean of N numbers in parallel.&lt;/p&gt; &lt;p&gt;There are two parts to the computation of the mean:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Compute the sum of all the numbers (data points).  &lt;/li&gt;&lt;li&gt;Divide the sum by the count of the numbers.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The first part can be done with a simple divide and conquer approach:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;If you have M processors, divide the N numbers to M processors to be summed in sequence.  &lt;/li&gt;&lt;li&gt;Aggregate the M sub-totals to come up with the total.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The second part can be done as a simple step.&lt;/p&gt; &lt;p&gt;This is by no means exciting, and if it were to be coded in C++ (using Boost.Asio and Boost.Thread) it may look a little something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;io_service pool;&lt;br&gt;&lt;/br&gt;shared_ptr&amp;lt;io_service::work&amp;gt; sentinel(new io_service::work(pool));&lt;br&gt;&lt;/br&gt;thread_group threads;&lt;br&gt;&lt;/br&gt;for (unsigned i=0; i &amp;lt; processors; ++i) &lt;br&gt;&lt;/br&gt;  threads.create_thread(&lt;br&gt;&lt;/br&gt;    bind(io_service::run, &amp;amp;pool)&lt;br&gt;&lt;/br&gt;    );&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;vector&amp;lt;int&amp;gt;::iterator begin=numbers.begin();&lt;br&gt;&lt;/br&gt;vector&amp;lt;int&amp;gt;::iterator end = begin;&lt;br&gt;&lt;/br&gt;size_t chunk_size = numbers.size() / processors;&lt;br&gt;&lt;/br&gt;vector&amp;lt;int&amp;gt; sums;&lt;br&gt;&lt;/br&gt;mutex sums_mutex;&lt;br&gt;&lt;/br&gt;do {&lt;br&gt;&lt;/br&gt;  advance(end, chunk_size);&lt;br&gt;&lt;/br&gt;  pool.post(&lt;br&gt;&lt;/br&gt;    bind(&lt;br&gt;&lt;/br&gt;      sum_range, ref(sums), ref(sums_mutex), begin, end&lt;br&gt;&lt;/br&gt;      )&lt;br&gt;&lt;/br&gt;    );&lt;br&gt;&lt;/br&gt;} while (end != numbers.end());&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;sentinel.reset();&lt;br&gt;&lt;/br&gt;threads.join_all();&lt;br&gt;&lt;/br&gt;int total_sum = accumulate(sums.begin(), sums.end(), 0);&lt;br&gt;&lt;/br&gt;double average = &lt;br&gt;&lt;/br&gt;  numeric_cast&amp;lt;double&amp;gt;(total_sum) &lt;br&gt;&lt;/br&gt;  / numeric_cast&amp;lt;double&amp;gt;(numbers.size())&lt;br&gt;&lt;/br&gt;  ;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The missing part from the above snippet is the sum_range function which actually adds the sub-ranges and then adds the data to the sums vector:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;void sum_range(vector&amp;lt;int&amp;gt; &amp;amp; sums, mutex &amp;amp; sums_mutex, vector&amp;lt;int&amp;gt;::iterator begin, vector&amp;lt;int&amp;gt;::iterator end) {&lt;br&gt;&lt;/br&gt;  int intermediary_sum = accumulate(begin, end, 0);&lt;br&gt;&lt;/br&gt;  { // new scope for scoped_lock&lt;br&gt;&lt;/br&gt;    scoped_lock lock(sums_mutex);&lt;br&gt;&lt;/br&gt;    sums.push_back(intermediary_sum);&lt;br&gt;&lt;/br&gt;  }&lt;br&gt;&lt;/br&gt;};&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This is really simple but you can imagine that a lot of computations when it comes to statistics involves performing operations on ranges of values and computing certain aspects of the data that seem important. This is just a starter, and you can imagine that larger chunks of data can be dealt with more quickly if you explore the parallelism available in the computations you're making.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Conclusions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;By far I've shown one possible approach to converting something serial (computing the sum of numbers) into something parallel. Only by going parallel will serial algorithms be able to take advantage of the next wave of multi-core architectures that are already available today and that will only increase in the future.&lt;/p&gt; &lt;p&gt;In the next few articles I'll delve deeper into a different kind of parallelism: fine-grained parallelism. These kinds of &quot;chunky&quot; computations I've shown above leverage the number of available processors to still do serial computations. However, the kinds of computations for fine-grained parallel applications are way different where data items are dealt with on a more granular level.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;This is part of a running series of posts regarding parallel computing and parallel programming. If you have questions regarding the material or the subject and you don't feel like posting them as comments, send the author an email through &lt;a href=&quot;mailto:dean.berris@cplusplus-soup.com&quot;&gt;dean.berris@cplusplus-soup.com&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=EpNcoQay&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=41&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=MdnBFqgL&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=42&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=IjOKpI5g&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=43&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=QfOhVljG&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=50&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Oxu7Y7eN&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=Oxu7Y7eN&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=W5mRtjgN&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=W5mRtjgN&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=Jy8aIEPk&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=45&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=5HOtpGpy&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?i=5HOtpGpy&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feedproxy.google.com/~f/CppSoup?a=M5SemN7n&quot;&gt;&lt;img src=&quot;http://feedproxy.google.com/~f/CppSoup?d=52&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feedproxy.google.com/~r/CppSoup/~4/K7f2dHU4Mqs&quot; height=&quot;1&quot; width=&quot;1&quot;&gt;&lt;/img&gt;</description>
	<pubDate>Tue, 28 Oct 2008 10:09:59 +0000</pubDate>
	<author>mikhailberis@gmail.com (Dean Michael)</author>
</item>
<item>
	<title>Christian Chiu: SQL Case Problem - Solved with an Alternative Query</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-4761561117183058959.post-8332387899277042924</guid>
	<link>http://xt-onb.blogspot.com/2008/10/sql-case-problem-solved-with.html</link>
	<description>Yes! I did it. I was able to have an alternative query (Thanks to paxi for the initial UNION idea). As you can see, the code is longer than the one I posted yesterday, but then it is able to display what I need... perfectly.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;I have here 3 SELECT statements, 2 of which are under the main SELECT and are combined thru UNION.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;To evaluate these 2 SELECT statements, the first one is for the debit while the other one is for the credit. You may notice that in the intended debit select, I added NULL AS CREDIT and in the credit select counterpart, I added NULL AS DEBIT. This is because the UNION syntax requires me to have the two SELECT statements return tables that are equivalent (Same column data types and order).&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;And the SQL Query:&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;SELECT     ABS(debit) AS debit, ABS(credit) AS credit, title FROM&lt;br&gt;&lt;/br&gt;(&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;SELECT     entry_account.balance AS debit, null AS credit, accounts.title, entry_account.entry_id&lt;br&gt;&lt;/br&gt;FROM (entry_account INNER JOIN accounts ON entry_account.account_id = accounts.id)&lt;br&gt;&lt;/br&gt;WHERE (accounts.normal_balance = 'D') AND (entry_account.balance &amp;gt;= 0) OR (accounts.normal_balance = 'C') AND (entry_account.balance &amp;lt; 0)&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;UNION&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;SELECT null AS debit, entry_account_1.balance AS credit, accounts_1.title,  entry_account_1.entry_id&lt;br&gt;&lt;/br&gt;FROM (entry_account entry_account_1 INNER JOIN accounts accounts_1 ON   entry_account_1.account_id = accounts_1.id)&lt;br&gt;&lt;/br&gt;WHERE     (accounts_1.normal_balance = 'C') AND (entry_account_1.balance &amp;gt;= 0) OR (accounts_1.normal_balance = 'D') AND (entry_account_1.balance &amp;lt; 0)&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;) derivedtbl_1&lt;br&gt;&lt;/br&gt;WHERE     (entry_id = ?)&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;sweet...&lt;br&gt;&lt;/br&gt;   &lt;p class=&quot;multiply:no_crosspost&quot;&gt;&lt;/p&gt;</description>
	<pubDate>Mon, 27 Oct 2008 13:06:57 +0000</pubDate>
	<author>christian.chiu@gmail.com (Xt)</author>
</item>
<item>
	<title>Christian Chiu: SQL Case Problem</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-4761561117183058959.post-7599681985378862154</guid>
	<link>http://xt-onb.blogspot.com/2008/10/sql-case-problem.html</link>
	<description>SELECT     (CASE WHEN entry_account.balance &amp;gt; 0 THEN entry_account.balance ELSE null END) AS debit, accounts.title&lt;br&gt;&lt;/br&gt;FROM         ((entry_account INNER JOIN&lt;br&gt;&lt;/br&gt;                      accounts ON entry_account.account_id = accounts.id) INNER JOIN&lt;br&gt;&lt;/br&gt;                      entry ON entry_account.entry_id = entry.id)&lt;br&gt;&lt;/br&gt;WHERE     (entry.id = ?)&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Basically, the above code simply wants to put a value in the debit column if entry_account.balance is &amp;gt; 0 else NULL is appended. This is not exactly what my business logic is but I just have to make it simpler to actually get myself familiarized with the CASE syntax.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;The problem is, it just doesn't work. I browsed a couple of code snippets and all of them don't give my an idea why my code is wrong.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Have to sleep now, I might just get the answer tomorrow.&lt;br&gt;&lt;/br&gt;   &lt;p class=&quot;multiply:no_crosspost&quot;&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 25 Oct 2008 16:45:03 +0000</pubDate>
	<author>christian.chiu@gmail.com (Xt)</author>
</item>
<item>
	<title>Ealden Escanan: Yes, it's another post about Struts!</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-18429480.post-3611208513207156282</guid>
	<link>http://blog.ealden.net/2008/10/yes-it-another-post-about-struts.html</link>
	<description>&lt;p&gt;Last week, I was reminded why I can't easily escape Struts 1 hell, and more importantly why I probably wouldn't want to escape it, at least any time soon.  &lt;/p&gt; &lt;p&gt;The former is a question of business value: the module is already working and there are other stories lined up that needs implementing.  In our case, we have quite a bit of polish work left as we count down the days until the release.  On the other hand, when you magically find time to actually do a re-implementation as with the latter it becomes a question if you'd actually like to go through one.  There are probably more important things to do, like count grass.  More so if the current implementation without safety harness or close to a lost cause code-wise.&lt;/p&gt; &lt;p&gt;That was last week.&lt;/p&gt; &lt;p&gt;This is mostly a rambling of sorts of the current situation of the web layer in my current project, as well as some realizations and steps to move forward.  This is also an excuse to blog again haha.  Migration is definitely no going to happen overnight.  The trick now is to migrate in stages: slowly pay off the technical debt until it's something that we can live with.  Some steps I came up with that I should write down before I forget them:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Make use of Struts 2's compatibility mode for Struts 1 Actions.  Migrating to Struts 2 is a combination of migrating the Actions and more importantly the views.  These two steps normally should be done at the same time, but if it's possible to do just one that should reduce the complexity of migration.  &lt;/li&gt;&lt;li&gt;Upgrade to a newer Struts 1 version.  We are currently at 1.2.8 and I believe Struts 2 needs at least Struts 1 Actions at 1.3.5 to be able to use them.  We used to have a base class for all Actions that overrode execute() in Struts 1's Action class to implement a MappingDispatchAction-like functionality (but poorly) and this made upgrading difficult.  We were able to remove this a few months back and instead use MappingDispatchAction so this should be doable.  &lt;/li&gt;&lt;li&gt;Test and code cleanup.  We came up with a testing framework for Struts 1 Actions that, while involved and highly coupled to Struts and web technologies, offered a quick and simple way to test Struts 1 Actions.  Should be helpful to capture the current behavior so the Action classes can be refactored safely.  There are more advanced techniques in working with legacy code but I am not yet familiar with them.  &lt;/li&gt;&lt;li&gt;Get XDoclet out.  We have model-derived ActionForms using XDoclet and I've developed this annoyance for it as its &quot;annotations&quot; are too fragile.  I figured having ActionForms coded gives more control and more flexibility than having them generated.&lt;/li&gt;&lt;/ol&gt;</description>
	<pubDate>Tue, 21 Oct 2008 14:38:51 +0000</pubDate>
	<author>noreply@blogger.com (Ealden Escañan)</author>
</item>
<item>
	<title>Jan Alonzo: catching up</title>
	<guid isPermaLink="false">http://www.unpluggable.com/?p=187</guid>
	<link>http://unpluggable.com/?p=187</link>
	<description>&lt;p&gt;Life’s been catching up with me lately as you can see from the number of posts I’ve written this year. Work’s been in full swing plus other company demands that you have to do outside of work hours. There’s also my studies which sometimes can be frustrating, not because it’s difficult, but because analysis and doing paperwork (i.e. assignments) can be really time consuming. And then outside of those two, I try to contribute to WebKit/Gtk as much as I can, even when sometimes it’s all drudgery commit other people’s patch kind of work (someone’s gotta commit those right?). But anyway, it’s all good. Learning and challenging myself is always, well, a challenge. Where does one find the time to do all the things they wanna do?&lt;/p&gt;</description>
	<pubDate>Thu, 16 Oct 2008 10:14:28 +0000</pubDate>
</item>
<item>
	<title>Joe Ledesma: O&amp;B Library</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8354184108953466792.post-5402542667424293037</guid>
	<link>http://onbworker.blogspot.com/2008/10/o-library.html</link>
	<description>What i like about working  in O&amp;amp;B is that we have a comprehensive library.  Our CEO bulk orders books every now and then to add to the growing library. The books that we have covers a broad domain, from technical books, PMBA books and even up to project domains like insurance, accounting, stocks and a lot more. I think that a library like this is a good investment in any company. First, it is a good and always available resource for accurate and comprehensive information to aid our work. Second, It creates a culture of learning inside the company. Lastly, it can be a source of inspiration for people to broaden their knowledge and explore other things that they don't know when they browse the comprehensive title listing in the library.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Reading a physical paper and ink book is an entirely different experience than reading an electronic copy of a book. It is easier to read and much more convenient in terms of time and location constraints. Having many copies per title is also a good idea because a group of people can read the same books and have discuss what they have learned from the books. In a way, discussing lessons learned and discussing various subject matters can also be seen as some sort of informal training to widen the knowledge of an individual.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Recently, there are a lot of new additions to the Onb library. Personally, i have only read a few books from the library mainly PMBA books and a few self help books. Right now, i'm reading &quot;Skills for New Managers&quot; from the new batch, It's an interesting book and by the way its written, the information is easy to absorb. There are other interesting titles that i have seen in the new batch of books and i hope to read some during the coming holidays.</description>
	<pubDate>Tue, 14 Oct 2008 18:28:43 +0000</pubDate>
	<author>noreply@blogger.com (City Farmer)</author>
</item>
<item>
	<title>Calen Legaspi: Current Readings</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-21284276.post-3576563736784478690</guid>
	<link>http://calenlegaspi.blogspot.com/2008/10/current-readings.html</link>
	<description>I'm currently reading &lt;a href=&quot;http://as.wiley.com/WileyCDA/WileyTitle/productCd-0471780499.html&quot;&gt;Balanced Scorecard, Step-by-Step, by Paul Niven&lt;/a&gt;.  The Balanced Scorecard is one of the most important management tools of the past century.  It's about identifying the key metrics in your company from every perspective, not just financial.  I'm developing the O&amp;amp;B's Balanced Scorecard as I read it.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Next on my reading list is &lt;a href=&quot;http://www.bbrt.org/resources/bbbook.html&quot;&gt;Beyond Budgeting, by Hope and Fraser&lt;/a&gt;.</description>
	<pubDate>Sat, 11 Oct 2008 22:24:45 +0000</pubDate>
	<author>noreply@blogger.com (Calen Martin D. Legaspi)</author>
</item>
<item>
	<title>Tommy Lim: Learning buffet</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-1289052455202800937.post-6189285482066543130</guid>
	<link>http://coffeeandclover.blogspot.com/2008/10/learning-buffet.html</link>
	<description>Calen says to capitalize on learning experiences. 

From the start I planned on making a code generator for the project.  In addition to making it less tedious and more interesting to work, I was also anticipating the benefits that it could bring to round 2.

So I did despite the inevitability of taking longer to finish than I would have otherwise.

So aside from finishing (well practically done</description>
	<pubDate>Fri, 10 Oct 2008 16:29:19 +0000</pubDate>
	<author>noreply@blogger.com (Tommy)</author>
</item>
<item>
	<title>Charo Nuguid: The challenges of recording a Skype call</title>
	<guid isPermaLink="false">http://www.thegeekettespeaketh.com/42 at http://www.thegeekettespeaketh.com</guid>
	<link>http://feeds.feedburner.com/~r/FairTradeTechnology/~3/425110877/challenges-recording-skype-call</link>
	<description>&lt;p&gt;Recently I received an email from the community manager of Box.Net. He wanted to talk to me about their product.  I didn't know how he came upon my blog and why he decided to contact me to talk about Box.Net.  Perhaps it was because of my recent post about DropBox.  Nevertheless, I thought it would be great to know more about his product.&lt;/p&gt;
&lt;p&gt;But this post isn't about that interview. Actually it's about the challenges I went through in preparation for the interview.  You see, the community manager wanted us to talk about their product.  By talk I would think he wanted to contact me via Skype.  And that's when my interesting journey started.&lt;span class=&quot;read-more&quot;&gt;&lt;a href=&quot;http://www.thegeekettespeaketh.com/content/challenges-recording-skype-call&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;  &lt;b&gt;READ MORE ABOUT IT »&lt;/b&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=t5cIM&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=t5cIM&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=TjEwM&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=TjEwM&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=j1t1M&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=j1t1M&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
	<pubDate>Sun, 28 Sep 2008 15:34:56 +0000</pubDate>
</item>
<item>
	<title>Calen Legaspi: The 2 Secrets of a Successful Software Consulting Company</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-21284276.post-6776416200123149866</guid>
	<link>http://calenlegaspi.blogspot.com/2008/09/2-secrets-of-successful-software.html</link>
	<description>Seems a lot of software consulting companies don't get it, so we'll give away our &quot;secret&quot;.  There's two keys to a successful consulting company:&lt;br&gt;&lt;/br&gt;&lt;ol&gt;&lt;li&gt;Recruitment&lt;/li&gt;&lt;li&gt;Training&lt;/li&gt;&lt;/ol&gt;Some companies try to replace #1 with more of #2.  They settle for second-string or third-string recruits and hope that spending enough money on training will be enough.  This is the approach I see with a lot of the bigger companies.  Let me tell you right now that by our own experience (and we're damn good trainers), all the training in the world won't arm an under-talented person with the decision-making and problem-solving ability that he/she needs in the project.  Furthermore, given the pace of change in software development, you need people who can &lt;span style=&quot;font-style: italic;&quot;&gt;train themselves&lt;/span&gt;, otherwise it's a monumental effort to keep their skills relevant.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Some companies, particularly the smaller ones, try to replace #2 with more of #1.  This is better than the first alternative, since good recruits, while expensive, can usually figure things out by themselves.  The problem is, as you scale out, it's hard to find people who have both the talent &lt;span style=&quot;font-style: italic;&quot;&gt;and experience&lt;/span&gt; not to screw up on the job.  I'm not just talking about more expensive salaries, I mean that even if you had all the money in the world there's just not enough of them out there!  So you start recruiting talented people who haven't had much experience yet, and you hope they'll learn on the job.  &quot;After all&quot;, many developers-turned-entrepreneurs think, &quot;I learned on the job as well, and look how I turned out.&quot;  But these entrepreneurs forget all the screw-ups they made while learning on the job, and they don't know how much these screw-ups cost the company they used to work for, in terms of lost confidence from clients, re-done work, etc.  So now, these talented but raw kids in your company will be learning from their own screw-ups, which you have to pay for.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;So that's it really.  Recruit and train.  And retain.  Okay, that's 3 secrets.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;By the way, &lt;a href=&quot;http://orangeandbronze.com/&quot;&gt;O&amp;amp;B&lt;/a&gt; is looking for partner consulting companies both to subcontract work to, and to expand to new markets.  We're more than willing to share our recruitment, training and retention tactics to any company that we partner with.</description>
	<pubDate>Fri, 26 Sep 2008 01:50:12 +0000</pubDate>
	<author>noreply@blogger.com (Calen Martin D. Legaspi)</author>
</item>
<item>
	<title>Charo Nuguid: One DropBox to rule them all!</title>
	<guid isPermaLink="false">http://www.thegeekettespeaketh.com/41 at http://www.thegeekettespeaketh.com</guid>
	<link>http://feeds.feedburner.com/~r/FairTradeTechnology/~3/425110878/one-dropbox-rule-them-all</link>
	<description>&lt;p&gt;&lt;img src=&quot;http://thegeekettespeaketh.com/files/logo_DropBox.png&quot; style=&quot;float: left; margin-top: 10px; margin-bottom: 10px; margin-right: 10px;&quot;&gt;&lt;/img&gt;Having a laptop and a netbook has left me with a slight problem on file synchronization.  For a while I was wondering what cross-platform app I could use to make sure the needed files on both computers stay the same.  I've gotten used to opening the netbook to write my blog notes whereever I am.  But when it comes to actually posting them on my blog, I find it much easier to do that from my laptop.  I found out about a neat program courtesy Rom Feria though which allows me to sync files without having to use USB storage. The added plus: I can access stuff online too!&lt;span class=&quot;read-more&quot;&gt;&lt;a href=&quot;http://www.thegeekettespeaketh.com/content/one-dropbox-rule-them-all&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;  &lt;b&gt;READ MORE ABOUT IT »&lt;/b&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=vEq0M&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=vEq0M&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=CcMjM&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=CcMjM&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?a=7gXFM&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/FairTradeTechnology?i=7gXFM&quot; border=&quot;0&quot;&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
	<pubDate>Mon, 22 Sep 2008 01:07:39 +0000</pubDate>
</item>

</channel>
</rss>
