<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-12142884</id><updated>2009-11-04T13:57:35.014-08:00</updated><title type="text">C++ Soup!</title><subtitle type="html">C++ Tips, Tricks, Reviews, and Commentary. &lt;br&gt;
By Dean Michael Berris &lt;a href="mailto:dean@cplusplus-soup.com"&gt;&amp;lt;dean@cplusplus-soup.com&amp;gt;&lt;/a&gt;</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/posts/full" /><link rel="alternate" type="text/html" href="http://blog.cplusplus-soup.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/full?start-index=26&amp;max-results=25" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>140</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/2.5/" /><link rel="self" href="http://feeds.feedburner.com/CppSoup" type="application/atom+xml" /><feedburner:emailServiceId>CppSoup</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry><id>tag:blogger.com,1999:blog-12142884.post-3665876837662826240</id><published>2009-10-03T07:07:00.001-07:00</published><updated>2009-10-03T07:07:19.429-07:00</updated><title type="text">Elements of Programming: A Review (Part 3)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HbdMpW5XSzuqkUudtFbIZ7nfnWM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HbdMpW5XSzuqkUudtFbIZ7nfnWM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HbdMpW5XSzuqkUudtFbIZ7nfnWM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HbdMpW5XSzuqkUudtFbIZ7nfnWM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;In &lt;a id="x4-g" href="http://blog.cplusplus-soup.com/2009/08/elements-of-programming-review-part-2.html" title="Part 2"&gt;Part 2&lt;/a&gt; I showed the beginnings of a generic Range library implementation that approaches the problem by implementing a generic algorithm that deals with a Concept of a Range. In this third installment to the review of the book &lt;a id="tvgn" href="http://www.informit.com/store/product.aspx?isbn=032163537X" title="Elements of Programming"&gt;Elements of Programming&lt;/a&gt; by &lt;a id="g.mc" href="http://en.wikipedia.org/wiki/Alexander_Stepanov" title="Alexander Stepanov"&gt;Alexander Stepanov&lt;/a&gt; and &lt;a id="dx3b" href="http://www.mcjones.org/paul/" title="Paul McJones"&gt;Paul McJones&lt;/a&gt;, I intend to present a logical thesis on how to approach application development at a higher level using generic programming techniques along with the strong mathematics and Concept-based approach that the book advocates.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Set-Up&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;So first, let's assume we're writing a simple application that takes a file input that contains a set of coordinates in a &lt;a id="j_lr" href="http://en.wikipedia.org/wiki/Cartesian_coordinate_system" title="cartesian plane"&gt;cartesian plane&lt;/a&gt;. These coordinates show a set of points connected to each other. This is a fully-connected graph.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Our application is supposed to read all the coordinates and then store it in memory when the application starts. First we don't specify what kind of data structure we use, just that we're going to put it in memory. Second, we don't assume how we store it in memory or whether we put it in a database of some sort -- just that we store it somewhere. Third, we don't know yet how each coordinate is stored but rather that we're just going to assume we're going to have it stored somehow.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;At this point of the description, the application isn't really that interesting. However what it's supposed to do is what's interesting.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ready for Input&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Once the application has read all the coordinates from the file, the application is then ready for input. At this state, the application will take the input from the standard input device (or std::cin) in the form of three numbers separated by white space -- which signifies another cartesian coordinate, and a threshold distance value.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;First, we assume that the numbers are within the range [-INTMAX,+INTMAX) where INTMAX is the largest possible value represented in an 'int'. Second, we assume that we can store the coordinate the same way we store a coordinate we read from the file. Third, the absolute value of the threshold is used -- therefore negative values become positive values.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;So far so good, but then we get to the meat of the application.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Problem/Solution&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;What we want to do is find all the coordinates that are within the threshold distance from the input coordinate and print to standard output the coordinates in the form "[x,y] d" where 'x' is the coordinate on the x axis, y is the coordinate on the y axis, and d is the distance to the input coordinate. If you draw a circle around the input coordinate at its center with radius of the threshold distance, then the coordinates that lie within the circle are those coordinates we're looking for.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;If you can imagine it in your head, what we're going to have to do is:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Compute the distance between each coordinate and the source coordinate.&lt;/li&gt;&lt;li&gt;Filter out the coordinates that aren't within the threshold distance.&lt;/li&gt;&lt;li&gt;Display each coordinate in the prescribed format through standard output.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Understandably, we should be able to use already available STL containers and algorithms to do this. We can even model each coordinate as a std::pair&amp;lt;int,int&amp;gt; -- and then store them in a list.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;In this first incarnation of the solution, we have a few distinct steps which are:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Load the coordinates from the file.&lt;/li&gt;&lt;li&gt;Get the distances and store it along with the pair into another list.&lt;/li&gt;&lt;li&gt;Filter this list and remove the lists that aren't within a certain distance.&lt;/li&gt;&lt;li&gt;Print the filtered list.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;There is nothing wrong with this implementation per se -- however I see that we have three lists. We can optimize this implementation by removing the filtered list, and then hand-writing the iteration of the list of coordinates and distances.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;b&gt;Concepts&lt;/b&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;So in this implementation we're seeing that there is a certain concept called the coordinate. These are some basic operations defined against a Coordinate that should be valid (via ADL perhaps):&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;coord_x(c)&lt;/li&gt;&lt;li&gt;coord_y(c)&lt;/li&gt;&lt;li&gt;distance(c1, c2)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;In these operations, we assume that 'c', 'c1', and 'c2' are instances of a type that models the Coordinate concept. This gives us a set of primitive operations which we can work with in our application. In this domain of coordinates, we can then count on having the distance between two coordinates and retrieving the x and y components of the coordinate.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Algorithms&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Here we can then define the algorithms we need to implement. In a generic (and orthogonal) fashion we find that we have a few basic algorithms required to satisfy the end result that we want to achieve in the program:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;read_coordinates(input_stream) -&amp;gt; range&amp;lt;input_iterator&amp;gt;&lt;/li&gt;&lt;li&gt;copy_filtered(coordinates, filter, render, output) -&amp;gt; void&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;The read_coordinates(input_stream) algorithm returns a range of values. For this case we use the Boost.Range concept of a Range which is a pair of iterators for the sake of brevity. Below is a simple implementation of the read_coordinates algorithm:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;template &amp;lt;class InputStream&amp;gt;&lt;br&gt;iterator_range&amp;lt;typename InputStream::iterator&amp;gt;&lt;br&gt;read_coordinates(InputStream &amp;amp; input_stream) {&lt;br&gt;&amp;nbsp;&amp;nbsp;return iterator_range&amp;lt;typename InputStream::iterator&amp;gt;(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;istream_iterator&amp;lt;coordinate&amp;gt;(input_stream),&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;istream_iterator&amp;lt;coordinate&amp;gt;()&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;);&lt;br&gt;}&lt;br&gt;&lt;br&gt;template &amp;lt;class InputStream&amp;gt;&lt;br&gt;InputStream &amp;amp; operator&amp;gt;&amp;gt;(InputStream &amp;amp; is, coordinate &amp;amp; c) {&lt;br&gt;&amp;nbsp;&amp;nbsp;is &amp;gt;&amp;gt; c.x &amp;gt;&amp;gt; c.y;&lt;br&gt;&amp;nbsp;&amp;nbsp;return is;&lt;br&gt;}&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;This version of read_coordinates relies on the std::istream_iterator&amp;lt;&amp;gt; template that relies on an overloaded shift right (operator&amp;gt;&amp;gt;) implementation that works with an istream and an instance of a coordinate type. This is why we overload the operator&amp;gt;&amp;gt; too above.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;The we look at the algorithm for copy_filtered(coordinates, filter, renderer, output). Below is this generic implementation that takes four arguments:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;template &amp;lt;class CoordinateRange, class Filter, class Renderer, class OutputIterator&amp;gt;&lt;br&gt;void copy_filtered(CoordinateRange coordinates, Filter filter, Renderer render, OutputIterator output) {&lt;br&gt;&amp;nbsp;&amp;nbsp;typename iterator_traits&amp;lt;CoordinateRange&amp;gt;::type iter = begin(coordinates),&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;end_ = end(coordinates);&lt;br&gt;&amp;nbsp;&amp;nbsp;while (iter != end_) {&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (filter(*iter)) {&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;*output++ = render(*iter++);&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;In the above algorithm we see that we treat coordinates as a range, and then iterate through each item to check if the filter algorithm returns true, we copy the rendered item to the output iterator. This is a very generic filter algorithm that we can use not only in the scope of the program we're building but also other programs. However, in our domain, we may encounter a few snags in terms of efficiency. Let me try and help by pointing out a few things:&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;In our application, we intend to filter based on the distance between a certain coordinate and the coordinates we read from the file. This means we have to compute the distance in the filter function and the render function.&lt;/li&gt;&lt;li&gt;The algorithm above assumes that the filter function will return only a bool. We can change it to get a pair of values instead, a boolean to indicate that it qualifies and the distance. The problem with that approach is that the algorithm then becomes very narrow and specific to our application.&lt;/li&gt;&lt;li&gt;The renderer's return type should be convertible to the output iterator's value type -- this kind of undue coupling is something that is a fact of generic programming (even the STL does this with the copy algorithm). However in our application, the renderer -- which presumably will turn a coordinate into a string given the format we intend to output, will also need to compute the distance.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;This isn't turning out very well for our approach; although we've identified the algorithms we'll be requiring and the concepts we're going to work with, we aren't able to make an implementation yet that is as efficient as hand-coding everything into a single loop. The first incarnation made too much use of memory by making different lists -- that approach won't scale if we have a huge list of coordinates to go through and we keep making extra lists. This second approach eliminates the intermediate lists but computes the distances between the input coordinate and each coordinate from the file twice.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Third Time's the Charm&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;So let's back up a bit here. Up until this point we've been trying to make generic algorithms from our simple program. Our first incarnation would work although it consumed too much memory. Our second incarnation was a little alright although we're doing multiple computations of the distance. Let's then see how we can do if we can introduce some laziness in our implementation.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;First, let's look at our mathematical requirements:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;We have a tuple (x,y) which represents a point in a two dimensional integral plane.&lt;/li&gt;&lt;li&gt;We have a function distance(p1, p2) which represents the distance between two points.&lt;/li&gt;&lt;li&gt;We want to filter the points whose distance from a source point is within a certain threshold value.&lt;/li&gt;&lt;li&gt;We want to print these points and their distance from the source point.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;From here we then transform this into a nested pseudocode representation:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;print( filter( _ &amp;lt; threshold, transform(distance(source, _), points) ) )&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;The idea above is that we want to "print" all "filtered" points, where the distance from a source is less than a threshold.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;First problem we encountered (and dealt with) was that we had intermediate lists. We then imaging dealing instead with iterators in this solution. Second problem was that we computed distance twice -- first in the filtering, and second time in the rendering.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;To solve both problems, we want to be able to transform each point as just a single tuple (x,y), into a bundling of the coordinate and the distance. So now we're looking at a tuple ((x,y), d) where d is the distance -- the reason we want to do this is so that we bundle the coordinate with the distance, so that we can filter them efficiently using our filter algorithm.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Let's see how we can implement our 'distance_bundler' function object:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;template &amp;lt;class C&amp;gt;&lt;/div&gt;&lt;div&gt;struct distance_bundler {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;typedef tuple&amp;lt;C, double&amp;gt; result_type;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;distance_bundler(C const &amp;amp; source) : source_(source) {}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;tuple&amp;lt;C, double&amp;gt; operator() (C coord) {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return make_tuple(coord, distance(source_, coord));&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;C source_;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;};&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;So here we've made an effort already to make a specific data representation using our approach. However, consider that we are using a generic 'distance' function which can be easily retrieved via Argument Dependent Lookup (ADL) based on the type C's namespace.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;Next we implement a unary predicate function that takes a coordinate-distance bundle, and returns true if the distance is within a threshold value. This is how we can implement that filtering predicate:&lt;br&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;struct within_threshold {&lt;div&gt;&amp;nbsp;&amp;nbsp;typedef bool result_type;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;within_threshold(double threshold) : threshold_(threshold) {}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;template &amp;lt;class C&amp;gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;bool operator() (tuple&amp;lt;C, double&amp;gt; distance_bundle) {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return get&amp;lt;1&amp;gt;(distance_bundle) &amp;lt; threshold_;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;double threshold_;&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;In both the preceding implementations, we can choose to use BCCL to make sure the type 'C' models the Coordinate concept. I purposely left that out here to yield more readable examples.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Our next step would be to transform a qualified coordinate and the distance to the source into a string which we can then output. Here we require a 'render' function which will turn a coordinate bundle into an STL string which we also implement:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;template &amp;lt;class C&amp;gt;&lt;/div&gt;&lt;div&gt;string render(C const &amp;amp; c) {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;ostringstream output_stream;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;output_stream &amp;lt;&amp;lt; "[" &amp;lt;&amp;lt; coord_x(c) &amp;lt;&amp;lt; "," &amp;lt;&amp;lt; coord_y(c) &amp;lt;&amp;lt; "]";&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;return output_stream.str();&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;struct bundle_printer {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;typedef string result_type;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;template &amp;lt;class C&amp;gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;string operator() (tuple&amp;lt;C, double&amp;gt; bundle) {&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ostringstream output_stream;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;output_stream &amp;lt;&amp;lt; render(get&amp;lt;0&amp;gt;(bundle)) &amp;lt;&amp;lt; " " &amp;lt;&amp;lt; get&amp;lt;1&amp;gt;(bundle);&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return output_stream.str();&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;Again above we can use the BCCL to enforce that the type 'C' models Coordinate.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Next thing we do is we combine these elements into a lazily-applied construction that uses Boost.Iterators to stitch together the individual moving parts. The code follows, which is explained in greater detail later.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;transform(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;make_filter_iterator(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;within_threshold(threshold),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;make_transform_iterator(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;begin(input_range),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;distance_bundler(source)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;make_filter_iterator(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;within_threshold(threshold),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;make_transform_iterator(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;end(input_range),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;distance_bundler(source)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;ostream_iterator&amp;lt;string&amp;gt;(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;cout, "\n"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;bundle_printer()&lt;/div&gt;&lt;div&gt;);&lt;/div&gt;&lt;/blockquote&gt;If you happen to be using Boost.RangeEx you can use the algorithm version that supports ranges:&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;transform(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;make_filtered_range(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;within_threshold(threshold),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;make_transformed_range(&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;input_range,&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;distance_bundler(source)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;ostream_iterator&amp;lt;string&amp;gt;(cout, "\n"),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;bundle_printer()&lt;/div&gt;&lt;div&gt;);&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;Or:&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none"&gt;&lt;div&gt;transform(&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;input_range&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;| transformed(distance_bundler(source))&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;| filtered(within_threshold(threshold)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;, ostream_iterator&amp;lt;string&amp;gt;(cout, "\n")&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;, bundle_printer()&lt;/div&gt;&lt;div&gt;);&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;So in the preceding three sample listings, instead of applying the algorithms to different containers we turn them into lazily-applied functions to each element in the input range. Here we feed directly from the file into memory (in the form of a coordinate object that has been read from the input stream) then apply the transformations and filtering as we go through the coordinates.&lt;br&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;We also preserve the information required from the initially applied function 'distance_bundler' by bundling it with the result so that it can be used in the filtering -- and therefore have the computed value of the distance only computed once. This chaining approach and using generic algorithms to solve problems is a key theme being proposed by the book at varying levels.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Conclusions&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Using the techniques espoused by the book "&lt;a id="cb7j" href="http://www.informit.com/store/product.aspx?isbn=032163537X" title="Elements of Programming"&gt;Elements of Programming&lt;/a&gt;" we can come up with a means of showing how we can use these techniques and apply them when building applications. Using generic algorithms and functions that do specific things at varying levels for both efficiency and correctness is a good practice that yields the desired result.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;One of the biggest thrusts of the book is that of composition using building block functions in order to solve problems without having to resort to overly complex structural solutions. Instead of relying on object oriented programming alone, we can leverage functional programming and generic programming techniques to achieve efficient and expressive code. The role of composition in problem solving and extending software in general is something developers should be using more and more.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Instead of trying to re-inventing algorithms we should strive first to see if there are already algorithm implementations out there that we can leverage to allow us to solve problems faster by implementing the parts that are specific to our application. Short of using frameworks, libraries that are generic enough lend themselves to better re-use in more contexts than niche targeted solutions in the form of frameworks and platforms.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;This concludes the three-part series on the coverage of the "&lt;a id="ajw6" href="http://www.informit.com/store/product.aspx?isbn=032163537X" title="Elements of Programming"&gt;Elements of Programming&lt;/a&gt;" book by &lt;a id="of9r" href="http://en.wikipedia.org/wiki/Alexander_Stepanov" title="Alexander Stepanov"&gt;Alexander Stepanov&lt;/a&gt; and &lt;a id="hcsa" href="http://www.mcjones.org/paul/" title="Paul McJones"&gt;Paul McJones&lt;/a&gt;. Post comments for questions, suggestions, clarifications, and further elaboration.&lt;/i&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-3665876837662826240?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=W42RlDoeatE:aiUodmERnSQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=W42RlDoeatE:aiUodmERnSQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=W42RlDoeatE:aiUodmERnSQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=W42RlDoeatE:aiUodmERnSQ:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=W42RlDoeatE:aiUodmERnSQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=W42RlDoeatE:aiUodmERnSQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/W42RlDoeatE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/3665876837662826240/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=3665876837662826240" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/3665876837662826240" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/3665876837662826240" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/W42RlDoeatE/elements-of-programming-review-part-3.html" title="Elements of Programming: A Review (Part 3)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/10/elements-of-programming-review-part-3.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-4478766237377219357</id><published>2009-08-28T23:04:00.000-07:00</published><updated>2009-08-28T23:59:22.742-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="updates" /><title type="text">Memcache++ Updates (New Releases!)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cUOm-6eprtVsDVlYbnz-NlWVqq4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cUOm-6eprtVsDVlYbnz-NlWVqq4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cUOm-6eprtVsDVlYbnz-NlWVqq4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cUOm-6eprtVsDVlYbnz-NlWVqq4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;The past week has been a big open source week for me which started from the weekend that spilled into the week. I've been updating and improving the implementation of the &lt;a href="http://deanberris.com/memcachepp"&gt;Memcache++ Client&lt;/a&gt; which I've released the first version of (0.9) last February 2008. One full year and some months afterwards I got an email from a former client who asked me if I can improve the client to handle newer memcache protocols that I first didn't need, and some older ones which he does need. Needless to say, I went at it and the product of which is a cleaner implementation that also supports more commands than it used to.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before I go dive into the details of the implementation, let me first give you a history on the Memcache protocol, why it's important, and the project that led to the development (and release) of the memcache++ client library.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;History&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So back in February 2007, I started work with one &lt;a href="http://www.friendster.com/"&gt;of the largest social networking sites in the world&lt;/a&gt;. While there, I found myself in the middle of a project that was meant to increase the performance and scalability of an internal service that was crucial to the proper functioning of the site. One of the approaches taken was to leverage memcached to store frequently accessed and seldom changing data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Without going through the whole project's history, we first used &lt;a href="http://people.freebsd.org/~seanc/libmemcache/"&gt;libmemcache&lt;/a&gt; which was the easiest thing to do at the time. It worked for a while, until we saw that there were some issues with the library because it made too many connections to the &lt;a href="http://www.danga.com/memcached/"&gt;memcached&lt;/a&gt; server and this degraded performance over time. This may have been addressed with tuning the server on which the software we wrote (which was in C++) was running on, but then that meant operational overhead if we added machines or later encountered a spike that causes the number of connections to balloon to an insane number. While it worked, it was not the scalable solution that we were looking for.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For a while we tried to stick with it, but performance and stability tests kept complaining that over time the application (because it opened and closed lots of connections to the memcached servers) became unstable and performance numbers would suffer. This meant we either had to abandon the memcached idea altogether or we just write our own library to access the memcached servers from scratch. So we tried the writing our own library approach, and we did it from the ground-up with C++ forgoing the C implementation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After a month or so of heavy development and integration work, we were finally able to meet the performance requirements of the internal service. Not only that, we were also able to make the library a separate component that just did what we needed -- access memcached, pool a set of connections to many servers, and re-use long-lived connections instead of opening and closing new sockets everytime we need to issue requests. The performance numbers were impressive and so we were happy that we got to where we needed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Open Source&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then the idea came to mind: why don't we open source this library that we worked so hard to implement internally to get us to the point where we wanted to be (in a position to succeed) -- after all, memcached was instrumental to the success of other sites and was open source, why not the client library? Besides, it's one way for us to give back to the open source community on which a lot of the software we've written is running on.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So after a short discussion with the powers that be, the library was open sourced on January 2008 -- the project was registered on Sourceforge and the first release was uploaded on February 2008. This was met with some buzz, but apparently there aren't a lot of C++ projects that required the use of a memcache client out in the open. It seems most of the web projects that needed memcache were written in languages other than C++ -- hardly disheartening, because just a short few days later some hits came through and there were some users out there who were thinking about using the client in their C++ applications too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why Memcache?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So is memcached just for the web? I'd say hardly so. Let me give you a few examples where you'd want to be able to use memcache in your non-web (C++) applications:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Multiple Reads, Minimal Writes -- if you have an application that does a huge number of selects from a database from multiple sources (maybe different threads or different machines) and the data being queried rarely changes or is not time-critical data, then that means you can safely cache this either in your application or to an external cache provider. This external cache provider can be memcached and since you can store practically anything in memcache, you can definitely leverage this and alleviate your database from the strain of multiple readers and infrequent writers.&lt;/li&gt;&lt;li&gt;Shared Data -- Say you have an application which appends information to a queue or a file and you'd like to be able to share this across many instances of your application, you might think about putting this data straight to a database and then querying the database anytime you need that data. The problem here is that your bottleneck becomes the Database and it's pretty hard to fix that bottleneck if you rely on it for your shared data needs. Enter memcached which supports "append" and "prepend" operations -- so instead of just writing to the DB, you can also append or prepend the data to a key in memcached and just query that across instances of your application.&lt;/li&gt;&lt;li&gt;Atomic Counters -- Sometimes you might want to keep just a count of the number of times something is done (say the number of times a particular piece of data is accessed or modified). Typically you'll use a DB too so that you can query this information anytime you need it -- problem is that sometimes operations where you do COUNT() on primary keys from a DB would be resource-intensive especially if you have a large table. Enter memcached's 'incr' and 'decr' operations where you can set a key to be '0' and merely increment that key when a piece of data is accessed or modified. You can then query this information as often as you like alleviating the strain this introduces to your database.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;There are all sorts of places in Enterprise or High Performance applications where you may opt to cache data and usually this is where memcached would be a good fit. Of course, if you just keep in mind that the data is just cache data and data you can afford to lose, then it fits perfectly into a solution where you can access the cache first (if it's not there, then go to the canonical source -- usually a database server).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Client&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Memcached is the server which maintains a hash map in memory -- mapping keys to values. Values can be anything, and keys can be strings that don't have control characters or spaces in it. It can be a UUID, an aggregated string, a random value, an MD5 hash, or just any string you want to associate data to. Although there's a lot of cool technology in the memcached server, the client we've released (and now I maintain) leverages this server-side technology by offering a fast and stable interface to setting and retrieving the data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Memcache++ client offers the following features:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Support for memcached's 'get', 'set', 'add', 'replace', 'append', and 'prepend' commands.&lt;/li&gt;&lt;li&gt;Supports redundancy pools where you can associate more than one memcached server to a pool identifier and when getting data from this pool you try all the members of the pool to retrieve the data; when setting data on this pool, all 'set', 'add', 'replace', 'append', and 'prepend' operations are mirrored across members of the pool for redundancy.&lt;/li&gt;&lt;li&gt;Uses persistent connections per memcache client handle: using one handle per thread allows you to maximize multi-core machines without having to synchronize operations on a single handle.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The latest release (came out last Wednesday, August 26, 2009) is &lt;a href="http://sourceforge.net/projects/memcachepp/files/"&gt;version 0.11.1&lt;/a&gt; which supports all the above features mentioned. In the following days I may release version 0.11.2 which adds a little more polish to the implementation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These releases are just gearing up for release 1.0 which should support the "compare and set" (cas) operation, multiple get support, proper 'incr' and 'decr' support, among other performance and implementation enhancements.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Try it Out!&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if you have a C++ application that you think would greatly benefit from a separate cache provider like memcached, try out the library and let me know what you think! Hopefully it allows you to achieve performance and stability too like it allowed us to have back then -- and up until now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can get the source code through two means:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/projects/memcachepp/files/latest"&gt;Download the latest from Sourceforge.net&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Checkout the Git repository: git://memcachepp.git.sourceforge.net/gitroot/memcachepp/memcachepp&lt;/li&gt;&lt;/ul&gt;&lt;i&gt;The author is also available for consulting in case you need to extend the library for your own needs and would rather not have the changes released as open source. The library is released under the &lt;a href="http://www.boost.org/LICENSE_1_0.txt"&gt;Boost Software License&lt;/a&gt; which allows for the library to be used in commercial and proprietary applications. It is a header-only library and requires Boost 1.38 and higher to use. Consulting or support inquiries may be sent through &lt;a href="http://www.deanberris.com/contact-me/"&gt;this form&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-4478766237377219357?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=B4x66DA6UMA:mOL0PQW_fhU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=B4x66DA6UMA:mOL0PQW_fhU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=B4x66DA6UMA:mOL0PQW_fhU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=B4x66DA6UMA:mOL0PQW_fhU:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=B4x66DA6UMA:mOL0PQW_fhU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=B4x66DA6UMA:mOL0PQW_fhU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/B4x66DA6UMA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/4478766237377219357/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=4478766237377219357" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4478766237377219357" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4478766237377219357" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/B4x66DA6UMA/memcache-updates-new-releases.html" title="Memcache++ Updates (New Releases!)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/08/memcache-updates-new-releases.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2954984609486106715</id><published>2009-08-09T01:35:00.000-07:00</published><updated>2009-08-16T04:49:08.166-07:00</updated><title type="text">Elements of Programming: A Review (Part 2)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-uHA4BpRvpwLPedgxLCt_t1JSpc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-uHA4BpRvpwLPedgxLCt_t1JSpc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-uHA4BpRvpwLPedgxLCt_t1JSpc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-uHA4BpRvpwLPedgxLCt_t1JSpc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;In &lt;a href="http://blog.cplusplus-soup.com/2009/08/elements-of-programming-review-part-1.html"&gt;Part 1&lt;/a&gt; I covered three major foundational concepts being put forth by &lt;a href="http://en.wikipedia.org/wiki/Alexander_Stepanov"&gt;Alexander Stepanov&lt;/a&gt; and &lt;a href="http://www.mcjones.org/paul/"&gt;Paul McJones&lt;/a&gt; in &lt;a href="http://www.informit.com/store/product.aspx?isbn=032163537X"&gt;Elements of Programming&lt;/a&gt;, their latest book published by &lt;a href="http://pearson.com/"&gt;Pearson Education&lt;/a&gt;. This post then attempts to apply the concepts in the book by putting forth some examples that were not lifted from the book, because it's already full of concrete samples and applications. In this installment in a three part series, I attempt to apply the generic programming foundational approach to building a simple range composition library.&lt;br /&gt;&lt;br /&gt;After reading the book I got more and more interested in programming in the style that Generic Programming [1][2] prescribes and to apply the concepts being taught. The highlight of the elements of programming is the deliberate and evolutionary process in which algorithms are implemented to be both efficient and generic. However, to get to the generic part we will need to start with the specific implementation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Concepts in Action&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Even if we won't be having language level support for Concepts in C++0x, we can still enforce concept checking using the &lt;a href="http://www.boost.org/doc/libs/1_39_0/libs/concept_check/concept_check.htm"&gt;Boost Concept Check&lt;/a&gt; library. This library has been around for quite a while already and provides an easy means of defining concepts and enforcing them on your algorithms with the C++98 and C++0x. I've in-lined a simple example of how we can use Concepts in our programs:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#include &amp;lt;boost/concept_check.hpp&amp;gt;&lt;br /&gt;&lt;br /&gt;template &amp;lt;class T&amp;gt;&lt;br /&gt;struct Foo : boost::DefaultConstructible&amp;lt;t&amp;gt; {&lt;br /&gt;  private:&lt;br /&gt;      T t;&lt;br /&gt;  public:&lt;br /&gt;      BOOST_CONCEPT_USAGE(Foo)&lt;br /&gt;      {&lt;br /&gt;          T c(t);     // T must be copy constructible&lt;br /&gt;          c.foo();    // T must have a nullary function foo&lt;br /&gt;      }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt;class T&amp;gt;&lt;br /&gt;void call(T &amp;amp; t) {&lt;br /&gt;  BOOST_CONCEPT_ASSERT((Foo&amp;lt;t&amp;gt;));&lt;br /&gt;  t.foo();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct a_foo {&lt;br /&gt;  void foo() { /* do nothing */ }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct not_a_foo {&lt;br /&gt;  void foo_() { /* do nothing */ }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(int argc, char * argv[]) {&lt;br /&gt;  a_foo foo_thing;&lt;br /&gt;  not_a_foo bar;&lt;br /&gt;&lt;br /&gt;  call(foo_thing); // ok&lt;br /&gt;  call(bar); // not ok, will fail&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;In the above sample, what's interesting is that the code will not compile and that's by design. This example is also meant to show how much more readable error messages are with Concepts:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;concepts_example.cpp: In function ‘void call(T&amp;amp;) [with T = not_a_foo]’:&lt;br /&gt;concepts_example.cpp:34:   instantiated from here&lt;br /&gt;concepts_example.cpp:18: error: ‘struct not_a_foo’ has no member named ‘foo’&lt;br /&gt;concepts_example.cpp: In destructor ‘Foo&amp;lt;t&amp;gt;::~Foo() [with T = not_a_foo]’:&lt;br /&gt;/home/dean/boost/boost/concept/detail/general.hpp:38:   instantiated from ‘static void boost::concepts::requirement&amp;lt;boost::concepts::failed************&amp;gt;::failed() [with Model = Foo&amp;lt;not_a_foo&amp;gt;]’&lt;br /&gt;concepts_example.cpp:17:   instantiated from ‘void call(T&amp;amp;) [with T = not_a_foo]’&lt;br /&gt;concepts_example.cpp:34:   instantiated from here&lt;br /&gt;concepts_example.cpp:11: error: ‘struct not_a_foo’ has no member named ‘foo’&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;This is something that's worth paying for (and having) if you write a lot of code that depends on concepts -- and if you intend to write generic algorithms. From here on I'll make use of implementations that expressly use concepts implemented using the Boost Concept Check Library (BCCL).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ranges&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the main theses of the book is that generic algorithms build upon basic Concepts and implement generic enough abstractions to make implementations re-usable and powerful in their own rights. The book talks a lot about the Iterator concept hierarchy in the Standard Template Library (STL) and how you can write algorithms that build upon these Iterator concepts and some "refinements" (or more narrow specific types of Iterator concepts).&lt;br /&gt;&lt;br /&gt;Briefly the book also covers a topic on Ranges that are represented as a pair of Iterators. Looking at this concept of a Range and the thoughts shared lately by &lt;a href="http://en.wikipedia.org/wiki/Andrei_Alexandrescu"&gt;Andrei Alexandrescu&lt;/a&gt; in his keynote address [3] in the recently concluded &lt;a href="http://www.boostcon.com/home"&gt;BoostCon&lt;/a&gt; 2009, I'm inclined to think that there is merit in what Andrei has been proposing -- that there may be something to be gained by making Ranges the primitive Concept to deal with when implementing generic algorithms that deal with a collection of data. Having said this, let me give you a short discourse into how you can implement this using a similar approach shown in the book.&lt;br /&gt;&lt;br /&gt;First let us define a simple concept we want to deal with: a Range. A Range allows us to do a finite number of things to it:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pop the element at the front of the range (pop_front(range)).&lt;/li&gt;&lt;li&gt;Get the element at the front of the range (front(range)).&lt;/li&gt;&lt;li&gt;Check if a range is empty (empty(range)).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;To put this in code, we need a Range concept that we should be able to check programmatically. The following listing shows a candidate definition of the minimal Range concept using BCCL:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;template &amp;lt;class R&amp;gt;&lt;br /&gt;struct Range : boost::DefaultConstructible&amp;lt;R&amp;gt;, boost::EqualityComparable&amp;lt;R&amp;gt; {&lt;br /&gt;    private:&lt;br /&gt;        R r;&lt;br /&gt;        typedef typename R::value_type value_type;&lt;br /&gt;    public:&lt;br /&gt;        BOOST_CONCEPT_USAGE(Range)&lt;br /&gt;        {&lt;br /&gt;            R c(r); // R must be copy constructible&lt;br /&gt;            pop_front(c); // support a pop_front action&lt;br /&gt;            value_type ref = front(c); // support a front action&lt;br /&gt;            bool result = empty(c); // check if a range is empty&lt;br /&gt;        }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;In the code above we define the syntactic requirements for a type R to model the Range Concept. We then implement a very simple range, a &lt;code&gt;counted_range&lt;/code&gt; which defines the numeric range from [0,max).&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;struct counted_range {&lt;br /&gt;    counted_range(size_t max = 0) : count_(0), max_(max) {}&lt;br /&gt;    counted_range(counted_range const &amp; other) : count_(other.count_), max_(other.max_) {}&lt;br /&gt;    bool operator==(counted_range const &amp; rhs) {&lt;br /&gt;        return ((rhs.count_ == count_) &amp;&amp; (rhs.max_ == max_));&lt;br /&gt;    }&lt;br /&gt;    bool operator!=(counted_range const &amp; rhs) {&lt;br /&gt;        return !(*this == rhs);&lt;br /&gt;    }&lt;br /&gt;    typedef size_t value_type;&lt;br /&gt;    private:&lt;br /&gt;    friend void pop_front(counted_range &amp;);&lt;br /&gt;    friend size_t front(counted_range &amp;);&lt;br /&gt;    friend bool empty(counted_range &amp;);&lt;br /&gt;    size_t count_, max_;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void pop_front(counted_range &amp; range) {&lt;br /&gt;    ++range.count_;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;size_t front(counted_range &amp; range) {&lt;br /&gt;    return range.count_;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;bool empty(counted_range &amp; range) {&lt;br /&gt;    return range.count_ &amp;gt;= range.max_;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Note in the implementation that we didn't define member functions but rather relied upon free functions -- this is by design because our Range Concept definition requires free functions &lt;code&gt;pop_front&lt;/code&gt;, &lt;code&gt;empty&lt;/code&gt;, and &lt;code&gt;front&lt;/code&gt;. Now that we have a simple definition of a &lt;code&gt;counted_range&lt;/code&gt; all we need to do is write an algorithm that actually requires the Range concept. Let's see a simple algorithm named &lt;code&gt;count&lt;/code&gt; which will just count the number of elements in a Range.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;template &amp;lt;class R&amp;gt;&lt;br /&gt;BOOST_CONCEPT_REQUIRES(&lt;br /&gt;        ((Range&amp;lt;R&amp;gt;)),&lt;br /&gt;        (size_t)&lt;br /&gt;        )&lt;br /&gt;count(R range) {&lt;br /&gt;    size_t result = 0;&lt;br /&gt;    while (!empty(range)) {&lt;br /&gt;        pop_front(range);&lt;br /&gt;        ++result;&lt;br /&gt;    }&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;We can see here that we have a function &lt;code&gt;count&lt;/code&gt; that takes as a parameter an object &lt;code&gt;range&lt;/code&gt; of type R which models the Range Concept and returns a value of type &lt;code&gt;size_t&lt;/code&gt;. Note that we're dealing with a copy of the range, which allows us to mutate the range within the algorithm without having to deal with the original range.&lt;br /&gt;&lt;br /&gt;We can then call the &lt;code&gt;count&lt;/code&gt; algorithm a &lt;a href="http://en.wikipedia.org/wiki/Regular_function"&gt;regular function&lt;/a&gt; -- one that will return the same value given the same input. Because it is a regular function, we can then be sure that it will return the same value given a range of the same properties, and then use it in our higher level functions and be sure that we can count on &lt;code&gt;count&lt;/code&gt; (pardon the pun) to do the right thing every time it is called. Our only worry is that the &lt;a href="http://en.wikipedia.org/wiki/Codomain"&gt;codomain&lt;/a&gt; of the function is the set of values that can be represented with the &lt;code&gt;size_t&lt;/code&gt; type. That means, if you have a Range type that represents a range that has more than the maximum value that a &lt;code&gt;size_t&lt;/code&gt; can handle then either you have an invalid Range type or &lt;code&gt;count&lt;/code&gt; is ill-defined for that input.&lt;br /&gt;&lt;br /&gt;We then have two choices here: 1) we require the Range to support a &lt;code&gt;distance_type&lt;/code&gt; nested class which defines the type for the distance between the first and last element of a Range or 2) we refine the Range concept with another concept called a FiniteRange which defines a finite range (meaning the number of elements in the range can be counted) and has the &lt;code&gt;distance_type&lt;/code&gt; part of each type that models the FiniteRange Concept.&lt;br /&gt;&lt;br /&gt;I like choice 2 better because we can then have two more specific kinds of Ranges -- an InfiniteRange and a FiniteRange. We can then have classifications of FiniteRange concepts that refine further the FiniteRange type and possibly see ForwardRange, BidirectionalRange, RandomAccessRange, InputRange, etc.; I can then also imagine another set of InfiniteRange concepts that refine InifiniteRange and see a GeneratorRange, OutputRange, IdentityRange and others like so.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Further Thoughts&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What I attempted to show here without quoting entries from the book (which I definitely encourage everyone to get at least a copy of) is that using the techniques of being able to understand the relationship between concrete classes and the notion of Concepts allows us to approach problem solving in a more formal and generic manner. Being able to put requirements on the types of the parameters of functions and understanding the limitations and capabilities of our algorithms gives us better foundations to write solutions on top of.&lt;br /&gt;&lt;br /&gt;This means we should be able to &lt;span style="font-style:italic;"&gt;reason&lt;/span&gt; about our solutions and enforce the reasoning with the help of libraries like the BCCL. Because we are then able to reason about our solution we can build better software with more confidence that we actually know what is going on. Combine this with the generic programming approach of working from specifics to generics and you then have a method of building libraries and solutions that will withstand the test of time.&lt;br /&gt;&lt;br /&gt;Adopting a mindset of understanding the requirements on inputs of a function and also the implications of the output of a function gives us an understanding of the limitations and applicability of our solutions on a broad range of problems. Maybe we have an algorithm that will be efficient for a certain class of Concepts and better algorithms that will be more efficient with more refined classes of Concepts. Using both the Object Oriented nature along with the Functional and Generic nature of C++, we can then have a better chance of writing algorithms, programs, solutions, and applications that we can be confident about using equational reasoning.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Part 3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Part 3 I will attempt to construct a logical thesis that will show how to approach application development using the concepts put forth in the book. In the next (and last) installment of my review of the book I will put together an example that uses the BCCL, Boost.Test, and Boost.Asio.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;References&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[1] &lt;a href="http://en.wikipedia.org/wiki/Generic_programming"&gt;Generic Programming : Wikipedia Definition&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[2] &lt;a href="http://www.generic-programming.org/"&gt;generic-programming.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[3] &lt;a href="http://blip.tv/file/2432106"&gt;BoostCon 2009: Iterators Must Go!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;This is part 2 of a three-part series on the review of the &lt;a href="http://www.informit.com/store/product.aspx?isbn=032163537X"&gt;Elements of Programming&lt;/a&gt; book by &lt;a href="http://en.wikipedia.org/wiki/Alexander_Stepanov"&gt;Alexander Stepanov&lt;/a&gt; and &lt;a href="http://www.mcjones.org/paul/"&gt;Paul McJones&lt;/a&gt;. Comments, suggestions, and questions are welcome in the comments section. In case you prefer email, send them to the author through &lt;a href="mailto:me@deanberris.com"&gt;me@deanberris.com&lt;/a&gt; or &lt;a href="mailto:dean.berris@cplusplus-soup.com"&gt;dean.berris@cplusplus-soup.com&lt;/a&gt;. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2954984609486106715?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=Xz7XODr3kbk:Fwu_VRAdkVU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=Xz7XODr3kbk:Fwu_VRAdkVU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=Xz7XODr3kbk:Fwu_VRAdkVU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=Xz7XODr3kbk:Fwu_VRAdkVU:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=Xz7XODr3kbk:Fwu_VRAdkVU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=Xz7XODr3kbk:Fwu_VRAdkVU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/Xz7XODr3kbk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2954984609486106715/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2954984609486106715" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2954984609486106715" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2954984609486106715" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/Xz7XODr3kbk/elements-of-programming-review-part-2.html" title="Elements of Programming: A Review (Part 2)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/08/elements-of-programming-review-part-2.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2758592285106163916</id><published>2009-08-04T07:06:00.000-07:00</published><updated>2009-08-04T08:29:01.884-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><title type="text">Elements of Programming: A Review (Part 1)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sUdYSccvPYQVQODG3ltC0fQiC6c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sUdYSccvPYQVQODG3ltC0fQiC6c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sUdYSccvPYQVQODG3ltC0fQiC6c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sUdYSccvPYQVQODG3ltC0fQiC6c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Over the course of the past few months much has happened to me in my life. Besides getting &lt;a href="http://www.deanberris.com/mental-blabberings/2009/5/14/married.html"&gt;married to the love of my life&lt;/a&gt; (twice) and moving to a new job, I've received a review copy of the recently released &lt;a href="http://www.informit.com/store/product.aspx?isbn=032163537X"&gt;Elements of Programming&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Alexander_Stepanov"&gt;Alexander Stepanov&lt;/a&gt; and &lt;a href="http://www.mcjones.org/paul/"&gt;Paul McJones&lt;/a&gt;. What follows is my take on what I think of the book and why everyone -- and I say absolutely everyone -- who has been doing software engineering for quite a while already should get a copy of this book.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I personally think this book is as important to the field of software engineering (and programming in general) as how the &lt;i&gt;Principia&lt;/i&gt;&lt;i&gt; &lt;/i&gt;&lt;i&gt;Mathematica&lt;/i&gt; was to mathematics. This is the book which will give those who care about the craft of software engineering and problem solving with software the fundamental insight into how libraries and software packages meant to deal with real-life projects should be written. Consequently after reading this book you'd want to look at all your source code you ever wrote before and see how you can apply the concepts being taught in the book.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is how valuable I think this book is: I'll actually get multiple copies of the book as foundational reading for my team -- and pay for the copies myself if I have to. This is one of those books that I've come across where I think the price I pay to have a copy of it is definitely worth every penny if not even more.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enough of what I think; now I want to talk about what the book contains and why I'm raving about the book so much it's taken three paragraphs of this entry for me to get to this point. But first, let me give some "prerequisites":&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;If you haven't been programming in C++ before, get into it now if only to be able to understand what the principles and techniques being taught are. It's not a prerequisite that you are an expert in C++, but if you understand how to use templates in your own code that would be great.&lt;/li&gt;&lt;li&gt;If you didn't have a major in mathematics, you might want to keep an elementary algebra and discrete mathematics reference around. Having been a computer science major at one point in my life, I can now appreciate the application of Set Theory and Group Theory to practical software development. It would really help if you have solid mathematical background.&lt;/li&gt;&lt;li&gt;If you think this will be an easy read, adjust your expectations now. It's going to be really hard to just skim through without thinking and focusing. Remember how you read (or tried to read) your high school textbooks to prepare for an exam? Well I do, and I'd recommend you use the same focus and techniques to read and digest what this book is all about.&lt;/li&gt;&lt;li&gt;Keep a notebook close so that you can take notes about how your brain is changing the way you look at software engineering. I'm also recommending that you keep a notebook handy also so that you can paraphrase what you're thinking while going through the book and just keep track of the thoughts.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;One general word of caution: if you think the concepts are going way over your head, go back to the basics and the fundamentals. This is one general rule that you'd like to go back to when reading this book. If you don't understand one part, do your research and go back to the material -- it generally helps if you have time to actually digest it and focus as you read it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, the general style of the book is that of a textbook. There are no anecdotes and personal notes from the authors -- it feels like you're reading a collection of papers and building up a very grand case for the techniques and concepts to be shared. Alexander and Paul do a great job of keeping the material terse and yet be expressive enough to keep a reader engaged.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Second, the subject mater and tone is serious. This book does a great job of being timeless in its treatment of the subject. This is as clear cut as you'd want to get when you're dealing with the fundamentals of programming and software engineering. The authors keep it very serious and very "matter-of-fact" throughout the book and it drives the point that this book is definitely something that everyone should be able to understand and benefit from. They keep to facts and the subject very effectively without being clever about anything.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Third, the C++ they use is just the subset of the whole language; if C++0x would contain Concepts (which it won't as of the most recent developments) then the code in the book are the definitive examples of how to use the proposed feature set. Having said this, the authors provide an appendix that deals with the syntax used and the features you can leverage in C++ to make the code compile without Concepts support from the compiler.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having done the preliminaries, I'll go into some of the details in the book. In part 2 I will attempt to apply the concepts in the book, while in part 3 I will attempt to construct a logical thesis on how to approach application development using the techniques taught in the book. In this part I will highlight some of the important foundational concepts put forth by the book in three sections: Concepts, Composition, and Generalization.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Concepts&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Although C++0x won't contain Concepts, the book starts out with laying the foundations of types and values then graduates to Concepts. After laying the groundwork down for the foundations, the concept of Concepts wherein you describe a meta-class (a class of Types) that abide by a set of rigid qualifications are then described. Essentially, they introduce the concept of a Concept by looking at data, classes (types), and then by creating a generalization of types that model a Concept.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This clear treatment and discussion of Concepts is one of the most if not the only definitive text I've come across that deals with the subject matter. Short of the book on Generic Programming, the concise and matter-of-fact approach to describing and defining Concepts is the best I've read bar none.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What the whole book then depends upon is the notion that a higher level (or more generic) treatment of classes instead of dealing with a hierarchical view of types (as in Object Oriented Programming) by defining the requirements on a type -- that it supports certain operations applied to the type, that there are certain axioms that hold against a type, and that there are consistent complexity requirements on the algorithms that deal with instances of the type -- that we can write generic, efficient, and effective algorithms relying on types modelling Concepts. The Type Theory aspects relevant to generic programming become evident if we draw parallels between Haskell Type Classes and C++ Concepts; we can then begin to see how transformational and important Concepts can be for sufficiently complex software engineering projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Composition&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the big things that the book promotes is the approach to composition: that higher level or higher order functions can be (and most probably should be) composed of smaller specific functions. The type of composition is not very far from the functional programming concept of composition, but rather the notion that you solve bigger problems by solving other problems with relatively smaller solutions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The kind of composition being promoted by the book is the generic kind where once you define and operate with Concepts, that the algorithms that you compose are then generic enough to be applied to &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;any instance of a type that models the Concepts the algorithm was meant to work with&lt;/span&gt;. This is very powerful because this means that if you have an algorithm that deals with a broad range of types instead of just types that derive from a certain base, this increases the re-use value for the algorithms you implement (or the library you've written).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Much like how bottom-up programming is meant to make complex tasks easier to solve by solving smaller tasks first, the composition approach applies very well to complex application development projects. The book gives you a good and clear idea of how to go about doing this in your own project albeit in a subtle manner that lets you formulate the solutions by showing the techniques and allowing you to run away with it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Generalization&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What the book doesn't do is come straight at you with generalizations, but rather it deals with foundations and specifics first before generalizing. The reasoning behind this is like with Set or Group Theory, you can only extend to a greater set by defining rules and building upon predicates that apply to an individual. What the book teaches is that you first go specific then get generic progressively.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The book also doesn't first show you what the generic "formula" or "technique" is, but rather it deals with a specific area first and the solutions that pertain to that area and then extends it to a more generic setting. By building on previously developed concepts and techniques readers get a very good example of how to correctly generalize -- by using mathematical logic and foundations and different techniques of proof at an abstract level to reason about the solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just like how the math and computer science majors are taught in discrete mathematics, your generalization should always apply true for the specific cases covered by the generalization. Unless you can prove that your generalization is logically sound, then you don't have an assurance that your generalization is correct -- therefore it would make your generalization invalid. Knowing this and applying it to software engineering is nothing short of brilliant.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Parting Shots&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if you've read through this (lengthy) post up to here, I'll say it once more: get this book if you're looking to improve the way you do software engineering and programming. If you care for the art/science of programming and problem solving with programming languages, pick this book up and I'm positive you will come to the same conclusions as I've reached. It took me a while to write this because mainly I wanted to do the book justice by doing an in-depth look and understanding how important this book is to the field.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;More to come in the next parts where I attempt to apply the concepts and techniques promoted by the book in real-world application development projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;The author would like to thank &lt;a href="http://pearson.com/"&gt;Pearson Education&lt;/a&gt; for sending a copy of this very important piece of literature for review. For questions and suggestions, please post in the comments or send email to &lt;a href="mailto:me@deanberris.com"&gt;me@deanberris.com&lt;/a&gt; or &lt;a href="mailto:dean.berris@cplusplus-soup.com"&gt;dean.berris@cplusplus-soup.com&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Update:&lt;/b&gt; Minor typographical edits from "discreet" to "discrete" mathematics.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2758592285106163916?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=TTLx-pKt5fg:T0hcoyb7JBc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=TTLx-pKt5fg:T0hcoyb7JBc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=TTLx-pKt5fg:T0hcoyb7JBc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=TTLx-pKt5fg:T0hcoyb7JBc:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=TTLx-pKt5fg:T0hcoyb7JBc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=TTLx-pKt5fg:T0hcoyb7JBc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/TTLx-pKt5fg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2758592285106163916/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2758592285106163916" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2758592285106163916" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2758592285106163916" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/TTLx-pKt5fg/elements-of-programming-review-part-1.html" title="Elements of Programming: A Review (Part 1)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/08/elements-of-programming-review-part-1.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-7129980607256971830</id><published>2009-06-08T05:42:00.000-07:00</published><updated>2009-06-08T05:55:35.993-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><title type="text">Bloom Filters</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wmXZgHrpS4gwVtBDPvYBUqo-X0c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wmXZgHrpS4gwVtBDPvYBUqo-X0c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wmXZgHrpS4gwVtBDPvYBUqo-X0c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wmXZgHrpS4gwVtBDPvYBUqo-X0c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;During the weekend I was fascinated by a simple utility called a &lt;a href="http://en.wikipedia.org/wiki/Bloom_filter"&gt;Bloom Filter&lt;/a&gt;. From the Wikipedia entry:&lt;br /&gt;&lt;blockquote&gt;The &lt;b&gt;Bloom filter&lt;/b&gt;, conceived by Burton H. Bloom in 1970, is a space-efficient &lt;a href="http://en.wikipedia.org/wiki/Probabilistic" title="Probabilistic" class="mw-redirect"&gt;probabilistic&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Data_structure" title="Data structure"&gt;data structure&lt;/a&gt; that is used to test whether an &lt;a href="http://en.wikipedia.org/wiki/Element_%28mathematics%29" title="Element (mathematics)"&gt;element&lt;/a&gt; is a member of a &lt;a href="http://en.wikipedia.org/wiki/Set_%28computer_science%29" title="Set (computer science)"&gt;set&lt;/a&gt;. &lt;a href="http://en.wikipedia.org/wiki/Type_I_and_type_II_errors" title="Type I and type II errors"&gt;False positives&lt;/a&gt; are possible, but &lt;a href="http://en.wikipedia.org/wiki/Type_I_and_type_II_errors" title="Type I and type II errors"&gt;false negatives&lt;/a&gt; are not. Elements can be added to the set, but not removed (though this can be addressed with a counting filter). The more elements that are added to the set, the larger the probability of false positives.&lt;/blockquote&gt;So I tried implementing my own generic Bloom Filter in C++ and submitted it to the &lt;a href="http://www.boost.org/"&gt;Boost C++ Libraries&lt;/a&gt;. My &lt;a href="http://article.gmane.org/gmane.comp.lib.boost.devel/190192"&gt;email&lt;/a&gt; went a little something like this:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;&lt;br /&gt;During the weekend, I got acquainted with and excited about Bloom&lt;br /&gt;Filters and the utility of such a data structure. I then proceeded to&lt;br /&gt;look at generic implementations of a bloom filter and I thought about&lt;br /&gt;implementing one myself instead as a simple exercise.&lt;br /&gt;&lt;br /&gt;Attached is what I came up with which I'm submitting as a library for&lt;br /&gt;review (and uploading to the vault). Also attached is a sample program&lt;br /&gt;which uses the bloom_filter.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/pre&gt;This then led to a few responses, and now I'm proud to say that my implementation can now be checked out and tracked from Boost Sandbox! The URL to the subversion repository is:&lt;br /&gt;&lt;pre&gt;&lt;a rel="nofollow" href="https://svn.boost.org/svn/boost/sandbox/bloom_filter/trunk/" target="_top"&gt;&lt;/a&gt;&lt;blockquote&gt;&lt;a rel="nofollow" href="https://svn.boost.org/svn/boost/sandbox/bloom_filter/trunk/" target="_top"&gt;https://svn.boost.org/svn/boost/sandbox/bloom_filter/trunk/&lt;/a&gt;&lt;/blockquote&gt;&lt;/pre&gt;Have fun with the library, and I would definitely like to know what you think about it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-7129980607256971830?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=sXlhSsVie_o:qoH6GuPwwlw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=sXlhSsVie_o:qoH6GuPwwlw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=sXlhSsVie_o:qoH6GuPwwlw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=sXlhSsVie_o:qoH6GuPwwlw:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=sXlhSsVie_o:qoH6GuPwwlw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=sXlhSsVie_o:qoH6GuPwwlw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/sXlhSsVie_o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/7129980607256971830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=7129980607256971830" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7129980607256971830" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7129980607256971830" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/sXlhSsVie_o/bloom-filters.html" title="Bloom Filters" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/06/bloom-filters.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-6951512771982468064</id><published>2009-05-27T02:48:00.000-07:00</published><updated>2009-05-27T04:07:50.947-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">MapReduce without using MapReduce?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/B4dB6VKu6FFvqDeoaIw-Ru-cgY8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B4dB6VKu6FFvqDeoaIw-Ru-cgY8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/B4dB6VKu6FFvqDeoaIw-Ru-cgY8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B4dB6VKu6FFvqDeoaIw-Ru-cgY8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently I had the chance to work on a few distributed parallel computing solutions for data analytics. One of the interesting choices I've had to make is whether to use the &lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;MapReduce&lt;/a&gt; computing model (using &lt;a href="http://hadoop.apache.org/core/"&gt;Hadoop&lt;/a&gt;) or whether to come up with an adhoc way of doing it.&lt;br /&gt;&lt;br /&gt;At first it wasn't a very easy decision to make the forces I was facing were:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I haven't had experience working with Hadoop before, and the last thing I did with it is the sample program that comes with it. Although I can understand that it is easy to use, there are other operational issues to consider.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Hadoop requires that you put the data into the DFS and while this is convenient to deal with in a program, operationally that's usually not an option. Imagine dumping data from a huge (production) database and then massaging it into a format that you can deal with through Hadoop.&lt;/li&gt;&lt;li&gt;The MapReduce model works as a parallel computing model and is simple enough for the kinds of analytics I intend to do. However, implementing a framework from scratch seemed like a daunting challenge especially since there was already an existing solution in Hadoop.&lt;/li&gt;&lt;/ol&gt;Given the above thought process, I started looking elsewhere. One of the first things I turned to was the Boost C++ Library and remembered that Boost.MPI is available to be used. Since I was already using Boost in my projects, it seemed a logical choice to stick with it.&lt;br /&gt;&lt;br /&gt;I then proceeded to install &lt;a href="http://www.open-mpi.org/"&gt;OpenMPI&lt;/a&gt; which &lt;a href="http://www.boost.org/doc/libs/1_39_0/doc/html/mpi.html"&gt;Boost.MPI&lt;/a&gt; had been tested against. At first I was skeptical whether it would be possible to use it in a data-parallel solution granted that it is a message passing implementation. Then I wrote the code and found out that it was definitely possible to do MapReduce with MPI.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The MapReduce Pattern&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Basically there is a simple pattern behind the MapReduce computing model. There are two steps: the Map step and the Reduce step. In between you have shuffles, etc. but the gist is that you need a way to map computation to data, and the results of the individual computations are then reduced to yield the answer. It's basically a divide-and-conquer approach to dealing with data in parallel.&lt;br /&gt;&lt;br /&gt;If you were doing this with MPI, you'd start with the 'scatter' function call. In Boost.MPI, you'd have some code like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;vector&amp;lt;int,int&amp;gt; ranges;&lt;br /&gt;// populate ranges&lt;br /&gt;pair&amp;lt;int,int&amp;gt; range;&lt;br /&gt;scatter(world, ranges, range, 0);&lt;br /&gt;&lt;br /&gt;&lt;/int,int&gt;&lt;/int,int&gt;&lt;/pair&gt;&lt;/blockquote&gt;Once you have your ranges scattered, you then deal with the data you get in the individual nodes. Your ranges may represent bounds in the database, maybe a part of a file shared accross the cluster, or just a range of numbers. This is the easy part, now the challenge becomes the reduce part.&lt;br /&gt;&lt;br /&gt;With that you need to think a little bit about what kind of data structure you're going to be transmitting from the worker nodes to the root node -- and how to actually "merge" the results to yield what you need in the end. Once you're settled with that, you can then implement the merge (or the reduction step) as a function object. In the following example I implement a merge of maps of counts as a functor:&lt;br /&gt;&lt;blockquote&gt;struct merge_maps {&lt;br /&gt; map&lt;int,&gt; operator() (map&amp;lt;int,int&amp;gt; l, map&amp;lt;int,int&amp;gt; const &amp;amp; r) {&lt;br /&gt;   l.insert(r.begin(), r.end());&lt;br /&gt;   return l;&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;namespace boost { namespace mpi {&lt;br /&gt; template &amp;lt;&amp;gt;&lt;br /&gt; struct is_commutative&amp;lt;merge_maps,map&amp;lt;int,int&amp;gt; &amp;gt; : true_ {};&lt;br /&gt;}}&lt;br /&gt;&lt;/blockquote&gt;We then use it with the Boost.MPI 'reduce' implementation:&lt;br /&gt;&lt;blockquote&gt;map&amp;lt;int,int&amp;gt; partial_map; // partial from the nodes&lt;br /&gt;map&amp;lt;int,int&amp;gt; final_map; // the "merged" map&lt;br /&gt;reduce(world, partial_map, final_map, merge_maps(), 0);&lt;br /&gt;&lt;/blockquote&gt;After this step, you basically have the final results in the 'final_map'.&lt;br /&gt;&lt;br /&gt;And that's it! You have an adhoc MapReduce implementation using Boost.MPI!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Of Course...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This isn't really MapReduce, but with all this talk about parallel computing and massively parallel distributed computing you can say that there are many ways of addressing the issue using alternative technologies.&lt;br /&gt;&lt;br /&gt;It'd be nice to know how you deal with your parallel distributed computing needs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-6951512771982468064?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=gDSsIn5d1a8:xCL1VIeBWLc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=gDSsIn5d1a8:xCL1VIeBWLc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=gDSsIn5d1a8:xCL1VIeBWLc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=gDSsIn5d1a8:xCL1VIeBWLc:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=gDSsIn5d1a8:xCL1VIeBWLc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=gDSsIn5d1a8:xCL1VIeBWLc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/gDSsIn5d1a8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/6951512771982468064/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=6951512771982468064" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6951512771982468064" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6951512771982468064" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/gDSsIn5d1a8/mapreduce-without-using-mapreduce.html" title="MapReduce without using MapReduce?" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/05/mapreduce-without-using-mapreduce.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-7693003305929679891</id><published>2009-04-10T09:42:00.000-07:00</published><updated>2009-04-10T10:22:28.215-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><title type="text">Function Input Iterator (Boost Submission)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PSN-8OAyBV5Qg8yFZeOitsv0e6s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PSN-8OAyBV5Qg8yFZeOitsv0e6s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PSN-8OAyBV5Qg8yFZeOitsv0e6s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PSN-8OAyBV5Qg8yFZeOitsv0e6s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;A couple of weeks ago I've submitted an implementation of a "Function Input Iterator" that builds upon the implementation of the generator iterator adaptor. The function input iterator implementation uses a separate state object that tracks the state of the iterator. The state encapsulated by the iterator is used to compare whether two iterators are equal.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The library has been submitted as an additional library to the Boost.Iterators library and is part of the Trac ticket &lt;a href="https://svn.boost.org/trac/boost/ticket/2893"&gt;#2893&lt;/a&gt;. From the ticket submission, the following details are then quoted.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana; font-size: 13px; "&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Simply put a the function input iterator implementation wraps a nullary function object and allows for bounded iterators using an embedded state variable. The use case is for something like the following:&lt;/p&gt;&lt;pre class="wiki" style="background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: rgb(247, 247, 247); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(215, 215, 215); border-right-color: rgb(215, 215, 215); border-bottom-color: rgb(215, 215, 215); border-left-color: rgb(215, 215, 215); margin-top: 1em; margin-right: 1.75em; margin-bottom: 1em; margin-left: 1.75em; padding-top: 0.25em; padding-right: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; overflow-x: auto; overflow-y: auto; background-position: initial initial; "&gt;struct generator {  typedef int result_type;  generator() { srand(time(0)); }  result_type operator() () const { return rand(); } };  using namespace std; using namespace boost;  int main(int argc, char * argv[]) {  generator f;  copy(    make_function_input_iterator(f, infinite()),    make_function_input_iterator(f, infinite()),    ostream_iterator&lt;int&gt;(cout, " ")    );  return 0; } &lt;/pre&gt;&lt;p&gt;And if you don't want an infinite range, you can simply bound it:&lt;/p&gt;&lt;pre class="wiki" style="background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: rgb(247, 247, 247); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(215, 215, 215); border-right-color: rgb(215, 215, 215); border-bottom-color: rgb(215, 215, 215); border-left-color: rgb(215, 215, 215); margin-top: 1em; margin-right: 1.75em; margin-bottom: 1em; margin-left: 1.75em; padding-top: 0.25em; padding-right: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; overflow-x: auto; overflow-y: auto; background-position: initial initial; "&gt;copy(   make_function_input_iterator(f, 0),   make_function_input_iterator(f, 10),   ostream_iterator&lt;int&gt;(cout, " ") );&lt;/pre&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-7693003305929679891?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=l9pSKB6vQaI:IHQpvrH6E9w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=l9pSKB6vQaI:IHQpvrH6E9w:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=l9pSKB6vQaI:IHQpvrH6E9w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=l9pSKB6vQaI:IHQpvrH6E9w:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=l9pSKB6vQaI:IHQpvrH6E9w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=l9pSKB6vQaI:IHQpvrH6E9w:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/l9pSKB6vQaI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/7693003305929679891/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=7693003305929679891" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7693003305929679891" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7693003305929679891" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/l9pSKB6vQaI/function-input-iterator-boost.html" title="Function Input Iterator (Boost Submission)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/04/function-input-iterator-boost.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2095668251286719334</id><published>2009-03-15T15:39:00.001-07:00</published><updated>2009-03-15T16:00:46.230-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c++0x" /><category scheme="http://www.blogger.com/atom/ns#" term="functional" /><category scheme="http://www.blogger.com/atom/ns#" term="templates" /><category scheme="http://www.blogger.com/atom/ns#" term="experiment" /><title type="text">GCC C++0x Features Exploration</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1ADLXdJyDtAuGre6oXXaIp3Xs0o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1ADLXdJyDtAuGre6oXXaIp3Xs0o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1ADLXdJyDtAuGre6oXXaIp3Xs0o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1ADLXdJyDtAuGre6oXXaIp3Xs0o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the interest of exploration, I played around one Sunday afternoon with the C++0x features available from GCC 4.3.2 &lt;a class="footnote-reference" href="#id6" id="id1" name="id1"&gt;[1]&lt;/a&gt; -- to better see what I can use at work when I migrate the application I'm writing from the C++98 standard to the C++0x standard. To gauge the differences, I tried implementing a simple stream-fusion approach to simultaneously compute the the mean, minimum, and maximum in a collection of integers.&lt;/p&gt;&lt;p&gt;For a little background, let me try and describe what stream fusion is briefly. Simply:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt; &lt;br /&gt;&lt;dl class="docutils"&gt; &lt;br /&gt;&lt;dt&gt;&lt;strong&gt;Stream Fusion&lt;/strong&gt;&lt;/dt&gt; &lt;br /&gt;&lt;dd&gt;Technique of removing multiple loops over a container and performing the required computations in a single pass. This technique is meant to minimize the number of loop iterations hopefully to improve the performance of an application. &lt;a class="footnote-reference" href="#id7" id="id2" name="id2"&gt;[2]&lt;/a&gt;&lt;/dd&gt; &lt;br /&gt;&lt;/dl&gt;&lt;/blockquote&gt;&lt;p&gt;Stream fusion is a good way to improve performance in applications that deal with huge containers and that perform multiple passes on the container to do multiple things. Sometimes the technique is a little more tideous to apply than the naive solutions but when performance matters it's something you can try.&lt;/p&gt;&lt;p&gt;Let's look at a naive version of getting the mean, minimum, and maximum of&lt;br /&gt;an array of integers:&lt;/p&gt; &lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;int numbers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };&lt;br /&gt;int min = min_element(numbers, numbers + 10);&lt;br /&gt;int max = max_element(numbers, numbers + 10);&lt;br /&gt;double mean =&lt;br /&gt;    static_cast&amp;lt;double&amp;gt;(accumulate(numbers, numbers + 10))&lt;br /&gt;    / 10.0&lt;br /&gt;    ;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here, we have three loops that compute the mean, minimum, and maximum from&lt;br /&gt;the same container. From the way it looks, it's just fine that we have three loops since we just have 10 elements in the array.&lt;/p&gt;&lt;p&gt;But what if for example we were reading the integers from a file and we have millions of integers to deal with, then going over the file three times doesn't seem like a viable solution especially if performance matters. At that scale of the problem, you can count on performance being a big deal. It also doesn't make sense for us to keep everything in memory either because the data may not fit in memory or the data actually comes from an input&lt;br /&gt;iterator bound to a stream.&lt;/p&gt;&lt;p&gt;Stream fusion then becomes more obvious because the reason it's called stream fusion is because usually the computations are associated with going through data that comes from a stream. Going &amp;quot;back&amp;quot; in a stream usually doesn't make sense or performance-wise is very costly, so we try and keep&lt;br /&gt;the computation going as we consume items in the stream to save on space consumption and to get the performance enhancements.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;&lt;a id="stream-fusion-c-98-style" name="stream-fusion-c-98-style"&gt;Stream Fusion, C++98 Style&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;So first thing we try is to do stream fusion with the C++98 standard. We'll use the TR1 tuple implementation that comes with GCC and the standard algorithms as well as a special computation type we'll call&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt;. First, we'll think about how to simultaneously compute the mean, minimum, and maximum.&lt;/p&gt;&lt;p&gt;To do this, we'll have to be able to keep track of the following variables:&lt;/p&gt; &lt;br /&gt;&lt;blockquote&gt; &lt;br /&gt;&lt;ul class="simple"&gt; &lt;br /&gt;&lt;li&gt;&lt;strong&gt;minimum so far&lt;/strong&gt; : we'll call this MIN&lt;/li&gt; &lt;br /&gt;&lt;li&gt;&lt;strong&gt;maximum so far&lt;/strong&gt; : we'll call this MAX&lt;/li&gt; &lt;br /&gt;&lt;li&gt;&lt;strong&gt;total so far&lt;/strong&gt; : we'll call this ACC&lt;/li&gt; &lt;br /&gt;&lt;li&gt;&lt;strong&gt;count of elements dealt with so far&lt;/strong&gt; : we'll call this COUNT&lt;/li&gt; &lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;&lt;/blockquote&gt; &lt;br /&gt;&lt;p&gt;What we want to do is for each iteration of the loop, we'll look at one element and see if it's the minimum so far, maximum so far, add it to ACC, and increment COUNT. To do this in functional programming means we'll have to rely on a left-fold and make &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt; a binary function object taking a state variable and an element as the respective arguments to the function operator overload.&lt;/p&gt;&lt;p&gt;To make it as generic as possible, we implement &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt; as a polymorphic function object type. We come up with the C++98 compliant version of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt; below:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;struct mean_min_max {&lt;br /&gt;    template &amp;lt;class T, class U&amp;gt;&lt;br /&gt;         T operator() (T const &amp;amp; state, U const &amp;amp; element) const {&lt;br /&gt;            enum { MEAN, MIN, MAX, ACC, COUNT };&lt;br /&gt;            return make_tuple(&lt;br /&gt;                // This is the running mean...&lt;br /&gt;                static_cast&amp;lt;double&amp;gt;(get&amp;lt;ACC&amp;gt;(state) + element)&lt;br /&gt;                / static_cast&amp;lt;double&amp;gt;(get&amp;lt;COUNT&amp;gt;(state) + 1),&lt;br /&gt; &lt;br /&gt;                // This is the minimum so far&lt;br /&gt;                (get&amp;lt;COUNT&amp;gt;(state) == 0)?&lt;br /&gt;                    element&lt;br /&gt;                    : (get&amp;lt;MIN&amp;gt;(state) &amp;gt; element)?&lt;br /&gt;                        element&lt;br /&gt;                        : get&amp;lt;MIN&amp;gt;(state),&lt;br /&gt; &lt;br /&gt;                // This is the maximum so far&lt;br /&gt;                (get&amp;lt;COUNT&amp;gt;(state) == 0)?&lt;br /&gt;                    element&lt;br /&gt;                    : (get&amp;lt;MAX&amp;gt;(state) &amp;lt; element)?&lt;br /&gt;                        element&lt;br /&gt;                        : get&amp;lt;MAX&amp;gt;(state),&lt;br /&gt; &lt;br /&gt;                // This is the new value of ACC&lt;br /&gt;                get&amp;lt;ACC&amp;gt;(state)+element,&lt;br /&gt; &lt;br /&gt;                // This is the new value of the COUNT&lt;br /&gt;                get&amp;lt;COUNT&amp;gt;(state) + 1&lt;br /&gt;                );&lt;br /&gt;        }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;p&gt;We can then use this as the fourth argument to the call to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accumulate&lt;/span&gt;&lt;/tt&gt; while we use the tuple &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(0.0,&lt;/span&gt; &lt;span class="pre"&gt;0,&lt;/span&gt; &lt;span class="pre"&gt;0,&lt;/span&gt; &lt;span class="pre"&gt;0uL,&lt;/span&gt; &lt;span class="pre"&gt;0)&lt;/span&gt;&lt;/tt&gt; as the initial state of the left fold:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;double mean = 0.0;&lt;br /&gt;int min = 0, max = 0;&lt;br /&gt;tie(mean, min, max, ignore, ignore) =&lt;br /&gt;    accumulate(numbers, numbers + 10,&lt;br /&gt;            make_tuple(mean, min, max, 0uL, 0),&lt;br /&gt;            mean_min_max()&lt;br /&gt;            );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;If we notice the call to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accumulate&lt;/span&gt;&lt;/tt&gt; we'll see that there's nothing special about this construct. Sure, we've accomplished what we want to accomplish with just the C++98 standard. You might be wondering what the problem with the above implementation could be, and in the next section I'll detail what those issues are.&lt;/p&gt;  &lt;br /&gt;&lt;h2&gt;&lt;a id="stream-fusion-c-0x-style" name="stream-fusion-c-0x-style"&gt;Stream Fusion, C++0x Style&lt;/a&gt;&lt;/h2&gt; &lt;br /&gt;&lt;p&gt;Now in the above solution, we have quite a number of inefficiencies that aren't readily obvious. First of these are the inordinate number of copies we'll be doing when returning the tuple from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt;. In C++98 we're stuck with copies when returning data from functions. Unless we use something like an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;auto_ptr&amp;lt;...&amp;gt;&lt;/span&gt;&lt;/tt&gt; as a return and use the heap, we don't have move semantics.&lt;/p&gt;&lt;p&gt;But in C++0x, we now have support for move semantics as an addition to the language. We rely on two features: r-value references and the move library function. So first, let's talk a little about what r-value references are and why they're important.&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt; &lt;br /&gt;&lt;dl class="docutils"&gt; &lt;br /&gt;&lt;dt&gt;&lt;strong&gt;R-Value References&lt;/strong&gt;&lt;/dt&gt; &lt;br /&gt;&lt;dd&gt;R-value references are denoted by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/tt&gt; right after a type. This is used to denote that only temporary values and literal constants can be referred to by an r-value reference. These r-value references actually take on the storage of the temporary value thereby not needing to allocate new storage for a new variable. It is then said that the temporary is 'moved' from the original scope to the new scope without relying on copies and additional temporaries. &lt;a class="footnote-reference" href="#id8" id="id3" name="id3"&gt;[3]&lt;/a&gt;&lt;/dd&gt; &lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;With a C++0x implementation of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt; we can change a few things that would allow the solution to minimize on copies:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;struct mean_min_max {&lt;br /&gt;    template &amp;lt;class T, class U&amp;gt;&lt;br /&gt;         T &amp;amp;&amp;amp; operator() (T const &amp;amp; state, U const &amp;amp; element) const {&lt;br /&gt;            enum { MEAN, MIN, MAX, ACC, COUNT };&lt;br /&gt;            return move(&lt;br /&gt;                    make_tuple(&lt;br /&gt;                        // same as before&lt;br /&gt;                        )&lt;br /&gt;                   );&lt;br /&gt;        }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;p&gt;Here we change the result of the function call operator to be an r-value reference of type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;T&lt;/span&gt;&lt;/tt&gt; and that we should &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;move&lt;/span&gt;&lt;/tt&gt; the temporary created in the body to be returned into the storage of wherever the result is to be put. Instead of the compiler calling the copy constructor of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tuple&lt;/span&gt;&lt;/tt&gt;, it then relies on the move constructor (or a constructor that takes a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;T&lt;/span&gt; &lt;span class="pre"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/tt&gt; as&lt;br /&gt;the sole argument instead of a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;T&lt;/span&gt; &lt;span class="pre"&gt;const&lt;/span&gt; &lt;span class="pre"&gt;&amp;amp;&lt;/span&gt;&lt;/tt&gt;) to initialize the values of the appropriate members.&lt;/p&gt;&lt;p&gt;If you have enough iterations and are dealing with heavy objects, r-value reference returns and move semantics will save you a lot of unnecessary copies. The less copies you make, the better the performance you get.&lt;/p&gt;&lt;p&gt;Another chance where we can use this technique is at the call to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accumulate&lt;/span&gt;&lt;/tt&gt; where we move the initial temporary tuple instead of letting the compiler copy the tuple for us:&lt;/p&gt; &lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;double mean = 0.0;&lt;br /&gt;int min = 0, max = 0;&lt;br /&gt;tie(mean, min, max, ignore, ignore) =&lt;br /&gt;    accumulate(numbers, numbers + 10,&lt;br /&gt;            move(&lt;br /&gt;                make_tuple(mean, min, max, 0uL, 0)&lt;br /&gt;            ),&lt;br /&gt;            mean_min_max()&lt;br /&gt;            );&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;h2&gt;&lt;a id="gcc-and-c-0x-lambda-s" name="gcc-and-c-0x-lambda-s"&gt;GCC and C++0x Lambda's&lt;/a&gt;&lt;/h2&gt; &lt;br /&gt;&lt;p&gt;Unfortunately, GCC 4.3.2 doesn't yet support C++0x Lambda's &lt;a class="footnote-reference" href="#id9" id="id4" name="id4"&gt;[4]&lt;/a&gt;. I haven't checked yet if GCC 4.4.x &lt;a class="footnote-reference" href="#id10" id="id5" name="id5"&gt;[5]&lt;/a&gt; already supports it, but since lambda's aren't supported by the compiler I was testing, I'm not yet able to show a solution to the problem without testing it. However, if your compiler already supports the C++0x lambda's, you can go ahead and move body of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mean_min_max&lt;/span&gt;&lt;/tt&gt; function into a lambda like this:&lt;/p&gt; &lt;br /&gt;&lt;pre class="literal-block"&gt; &lt;br /&gt;double mean = 0.0;&lt;br /&gt;int min = 0, max = 0;&lt;br /&gt;typedef tuple&amp;lt;double, int, int, unsigned long, size_t&amp;gt; accumulator_tuple;&lt;br /&gt;tie(mean, min, max, ignore, ignore) =&lt;br /&gt;    accumulate(numbers, numbers + 10,&lt;br /&gt;            move(make_tuple(mean, min, max, 0uL, 0)),&lt;br /&gt;            accumulator_tuple &amp;amp;&amp;amp;&lt;br /&gt;            [](accumulator_tuple &amp;amp; const state, int const &amp;amp; element) {&lt;br /&gt;                enum { MEAN, MIN, MAX, ACC, COUNT };&lt;br /&gt;                return move(&lt;br /&gt;                    make_tuple(&lt;br /&gt;                        // same as before&lt;br /&gt;                        )&lt;br /&gt;                    );&lt;br /&gt;            }&lt;br /&gt;            );&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;p&gt;If you're just making throw-away functions, lambda's are an attractive approach to keep the context of the computation closer to the point where you need the computation to be done. This is great if you are adept at using the STL algorithms and are comfortable with functional programming principles.&lt;/p&gt;&lt;p&gt;In this example the Lambda's noticeably don't have parametric types in the construction. This is because C++0x are monomorphic -- which means they only have one form. This makes C++0x lambda's a little less flexible compared to hand-coded function objects that have template member overloads of the function call operator (like our version).&lt;/p&gt; &lt;br /&gt;&lt;h2&gt;&lt;a id="more-to-come" name="more-to-come"&gt;More to Come&lt;/a&gt;&lt;/h2&gt; &lt;br /&gt;&lt;p&gt;In this article I've highlighted important new features of C++0x which should allow developers to be more productive and be able to produce better performing code with R-value references, move semantics, and lambda's. There are a handful more new features upcoming at the language level which I would like to explore as well in upcoming articles.&lt;/p&gt;&lt;p&gt;All in all, C++0x allows you to write powerful and performant code that when combined with powerful idioms (like stream fusion) yields superior solutions. Even though the C++98 standard allows you to write good code, C++0x just allows you to write better code in more ways than one.&lt;/p&gt; &lt;br /&gt;&lt;table class="docutils footnote" frame="void" id="id6" rules="none"&gt; &lt;br /&gt;&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt; &lt;br /&gt;&lt;tbody valign="top"&gt; &lt;br /&gt;&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1" name="id6"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;GCC 4.3.2 &lt;a class="reference" href="http://gcc.gnu.org/gcc-4.3/"&gt;http://gcc.gnu.org/gcc-4.3/&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;&lt;/tbody&gt; &lt;br /&gt;&lt;/table&gt; &lt;br /&gt;&lt;table class="docutils footnote" frame="void" id="id7" rules="none"&gt; &lt;br /&gt;&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt; &lt;br /&gt;&lt;tbody valign="top"&gt; &lt;br /&gt;&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2" name="id7"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Stream Fusion &lt;a href="http://www.cse.unsw.edu.au/~dons/papers/CLS07.html"&gt;http://www.cse.unsw.edu.au/~dons/papers/CLS07.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;&lt;/tbody&gt; &lt;br /&gt;&lt;/table&gt; &lt;br /&gt;&lt;table class="docutils footnote" frame="void" id="id8" rules="none"&gt; &lt;br /&gt;&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt; &lt;br /&gt;&lt;tbody valign="top"&gt; &lt;br /&gt;&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id3" name="id8"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;R-value References &lt;a href="http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2004/n1690.html"&gt;http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2004/n1690.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;&lt;/tbody&gt; &lt;br /&gt;&lt;/table&gt; &lt;br /&gt;&lt;table class="docutils footnote" frame="void" id="id9" rules="none"&gt; &lt;br /&gt;&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt; &lt;br /&gt;&lt;tbody valign="top"&gt; &lt;br /&gt;&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id4" name="id9"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Lambda's &lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;http://en.wikipedia.org/wiki/C%2B%2B0x&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;&lt;/tbody&gt; &lt;br /&gt;&lt;/table&gt; &lt;br /&gt;&lt;table class="docutils footnote" frame="void" id="id10" rules="none"&gt; &lt;br /&gt;&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt; &lt;br /&gt;&lt;tbody valign="top"&gt; &lt;br /&gt;&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id5" name="id10"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;GCC 4.4.x &lt;a class="reference" href="http://gcc.gnu.org/gcc-4.4/changes.html"&gt;http://gcc.gnu.org/gcc-4.4/changes.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;&lt;/tbody&gt; &lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2095668251286719334?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=x5M5LRjbZ_Y:Ewd5Pr5riFw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=x5M5LRjbZ_Y:Ewd5Pr5riFw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=x5M5LRjbZ_Y:Ewd5Pr5riFw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=x5M5LRjbZ_Y:Ewd5Pr5riFw:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=x5M5LRjbZ_Y:Ewd5Pr5riFw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=x5M5LRjbZ_Y:Ewd5Pr5riFw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/x5M5LRjbZ_Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2095668251286719334/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2095668251286719334" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2095668251286719334" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2095668251286719334" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/x5M5LRjbZ_Y/gcc-c0x-features-exploration.html" title="GCC C++0x Features Exploration" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/03/gcc-c0x-features-exploration.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-5287888062693084670</id><published>2009-03-09T04:20:00.000-07:00</published><updated>2009-03-09T20:56:06.884-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="project" /><title type="text">New Specification Library Release (0.2.1)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/btiQ4zW8mw8j0gOuwybkJjdthXs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/btiQ4zW8mw8j0gOuwybkJjdthXs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/btiQ4zW8mw8j0gOuwybkJjdthXs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/btiQ4zW8mw8j0gOuwybkJjdthXs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Recently, a few people have asked about my C++ implementation of a &lt;a href="http://www.behaviour-driven.org/"&gt;Behavior Driven Development&lt;/a&gt; library which was previously hosted at the &lt;a href="http://orangeandbronze.com/"&gt;Orange and Bronze&lt;/a&gt; website under my home directory. Apparently, there were a few changes made to the O&amp;amp;B site which disallowed my serving of the file releases from there so I thought about moving the file releases to my own domain. Having said that, there are a few things which have happened since the move, and I'm documenting those changes (and the new releases) in this blog entry.&lt;/p&gt;&lt;p&gt;If you haven't checked the site recently, I've added a dedicated file storage location for the &lt;a href="http://www.deanberris.com/spec-cpp/"&gt;Specification Library&lt;/a&gt; (which I've unimaginatively named as spec-cpp). From there you can get the latest releases of the library as well as get a sneak peak into what the library offers and supports.&lt;/p&gt;&lt;p&gt;The latest version line is the 0.2.x version which adds early container inspection support in the form of statements like:&lt;/p&gt;&lt;p style="padding-left: 30px;"&gt;container(some_container).should.contain(value);&lt;br /&gt;container(some_container).should.not_contain(value);&lt;br /&gt;container(some_container).should.not_be_empty();&lt;br /&gt;container(some_container).should.have_size(value);&lt;/p&gt;&lt;p&gt;More releases along the 0.2.x line will concentrate on inspecting STL and STL-conformant containers. As of the moment I develop the library on my free time and release all the source code as open source using the Boost Software License.&lt;/p&gt;&lt;p&gt;This release has been tested against &lt;a href="http://www.boost.org/users/news/version_1_38_0"&gt;Boost 1.38.0&lt;/a&gt; using the &lt;a href="http://gcc.gnu.org/gcc-4.3/"&gt;GCC 4.3.2&lt;/a&gt; compiler in Linux.&lt;/p&gt;&lt;p&gt;If you'd like to contribute or just get the latest and greatest version of the code, please head on over to the &lt;a href="http://github.com/"&gt;github&lt;/a&gt; repository at&amp;nbsp;&lt;a href="http://github.com/mikhailberis/spec-c--"&gt;http://github.com/mikhailberis/spec-c--&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;This blog post is cross-posted in &lt;a href="http://www.deanberris.com/"&gt;deanberris.com&lt;/a&gt; and &lt;a href="http://blog.cplusplus-soup.com/"&gt;blog.cplusplus-soup.com&lt;/a&gt; -- if you have questions or comments regarding the library, please send them to&amp;nbsp;&lt;a href="mailto:me@deanberris.com"&gt;me@deanberris.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; Adding correct link.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-5287888062693084670?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=SPu8IXlZaOI:Wagk7iWq6bI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=SPu8IXlZaOI:Wagk7iWq6bI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=SPu8IXlZaOI:Wagk7iWq6bI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=SPu8IXlZaOI:Wagk7iWq6bI:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=SPu8IXlZaOI:Wagk7iWq6bI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=SPu8IXlZaOI:Wagk7iWq6bI:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/SPu8IXlZaOI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/5287888062693084670/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=5287888062693084670" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/5287888062693084670" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/5287888062693084670" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/SPu8IXlZaOI/new-specification-library-release-021.html" title="New Specification Library Release (0.2.1)" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/03/new-specification-library-release-021.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-595665797959396574</id><published>2009-03-05T00:31:00.000-08:00</published><updated>2009-03-05T01:09:04.846-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="announcement" /><category scheme="http://www.blogger.com/atom/ns#" term="project" /><title type="text">Update: BDD in C++</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/owmx7XtTdi4npUpI_WuYk1yBVPk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/owmx7XtTdi4npUpI_WuYk1yBVPk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/owmx7XtTdi4npUpI_WuYk1yBVPk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/owmx7XtTdi4npUpI_WuYk1yBVPk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Because of recent changes in the &lt;a href="http://orangeandbronze.com/"&gt;Orange and Bronze Software Labs&lt;/a&gt; website, I had to move the source code for the Behavior Driven Development library that I wrote in C++ to a different host. Now, you can download the source code from &lt;a href="http://www.deanberris.com/spec-cpp/"&gt;http://www.deanberris.com/spec-cpp/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's been a while since this library has been used (last used it three years ago) and it would be nice to actively develop it again someday. Hopefully I can find the time to do it because it's a nice concept to play around it.&lt;br /&gt;&lt;br /&gt;Have fun, and I hope this helps!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; The Git repository is now hosted at Github, &lt;a href="http://github.com/mikhailberis/spec-c--/tree/master"&gt;http://github.com/mikhailberis/spec-c--/tree/master&lt;/a&gt; and adding link to O&amp;amp;B website.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-595665797959396574?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=OaQm3K-jzTw:JpPgklqQrOU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=OaQm3K-jzTw:JpPgklqQrOU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=OaQm3K-jzTw:JpPgklqQrOU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=OaQm3K-jzTw:JpPgklqQrOU:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=OaQm3K-jzTw:JpPgklqQrOU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=OaQm3K-jzTw:JpPgklqQrOU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/OaQm3K-jzTw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/595665797959396574/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=595665797959396574" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/595665797959396574" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/595665797959396574" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/OaQm3K-jzTw/update-bdd-in-c.html" title="Update: BDD in C++" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/03/update-bdd-in-c.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2803758883806064511</id><published>2009-03-03T19:13:00.001-08:00</published><updated>2009-03-03T19:23:46.250-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Intel Parallel Programming Talk: Featuring My Question</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SzKwC_5HiRgfcYqABxN2ztVqfTw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SzKwC_5HiRgfcYqABxN2ztVqfTw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SzKwC_5HiRgfcYqABxN2ztVqfTw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SzKwC_5HiRgfcYqABxN2ztVqfTw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently, I sent a question to the &lt;a href="http://www.blogtalkradio.com/MulticoreSoftware"&gt;Intel Parallel Programming Talk podcast&lt;/a&gt; about auto-parallelization at the compiler level. Yesterday, the episode aired and my question was picked and answered!&lt;br /&gt;&lt;br /&gt;You can listen to the episode online &lt;a href="http://www.blogtalkradio.com/MulticoreSoftware/2009/03/03/Developer-Listener-Questions-about-Parallel-Programming"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://www.blogtalkradio.com/BTRPlayer.swf?displayheight=&amp;file=http://www.blogtalkradio.com%2fMulticoreSoftware%2fplay_list.xml?show_id=431578&amp;autostart=false&amp;shuffle=false&amp;volume=80&amp;corner=rounded&amp;callback=http://www.blogtalkradio.com/FlashPlayerCallback.aspx&amp;width=215&amp;height=108" width="215" height="108" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" wmode="transparent" menu="false"&gt;&lt;/embed&gt;&lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzYxMzY5MDkyMzQmcHQ9MTIzNjEzNjkyODI1MCZwPTQ1MDk3MiZkPSZnPTEmdD*mbz*4NjI*ZWIyZDU2Mjg*NjZhYjRmOWRkYzlhN2Y*MmYxNg==.gif" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2803758883806064511?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UbBRJhw9Qs0:HTbNreSyU1k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UbBRJhw9Qs0:HTbNreSyU1k:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UbBRJhw9Qs0:HTbNreSyU1k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UbBRJhw9Qs0:HTbNreSyU1k:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UbBRJhw9Qs0:HTbNreSyU1k:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UbBRJhw9Qs0:HTbNreSyU1k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/UbBRJhw9Qs0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2803758883806064511/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2803758883806064511" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2803758883806064511" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2803758883806064511" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/UbBRJhw9Qs0/intel-parallel-programming-talk.html" title="Intel Parallel Programming Talk: Featuring My Question" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/03/intel-parallel-programming-talk.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2360663411940452937</id><published>2009-03-03T00:58:00.000-08:00</published><updated>2009-03-03T01:39:25.913-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="functional" /><title type="text">FP and C++: A Left Fold Fibonacci Implementation</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-4oDBIlz_-7Mvjhar8IgPH1yQYE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-4oDBIlz_-7Mvjhar8IgPH1yQYE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-4oDBIlz_-7Mvjhar8IgPH1yQYE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-4oDBIlz_-7Mvjhar8IgPH1yQYE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;So today, I was tinkering around with doing functional programming in C++ and thought about implementing one of the traditionally recursively implemented Fibonacci sequence generator. The classic problem is how would you write a function "fib" such that given a parameter "n" it will yield the nth fibonacci number.&lt;br /&gt;&lt;br /&gt;The traditional implementation (recursive) would look like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;unsigned long fib(int n) {&lt;br /&gt;  if (n &lt;= 1uL) return 1uL;&lt;br /&gt;  return fib(n - 2) + fib(n - 1);&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So that's not particularly surprising nor efficient (space or runtime-wise).  So we then think about how we can optimize it. Some people will think about memoization where we'll remember previously computed fibonacci numbers so the next time we compute it we'll benefit form cached values. That's alright because it amortizes the running time as you call the fib function more and more.&lt;br /&gt;&lt;br /&gt;If you don't know it yet, there's actually a way to get fibonacci numbers with an  linear (O(n)) running time algorithm. It's no fun implementing a loop ourselves, and to show that it's possible in C++, we use the existing numeric algorithm 'accumulate' which behaves precisely as a left fold.&lt;br /&gt;&lt;br /&gt;First, we need to implement the function object that will actually perform the binary operation that will yield the accumulated value. The good thing with the binary function object we're going to write is that the left parameter can have a different type from the right parameter. We can then use this to return a 'state' variable that is preserved as the left parameter of the next invocation of the function object.&lt;br /&gt;&lt;br /&gt;Let's see the code as we would write it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;struct fibonacci_folder {&lt;br /&gt;  template &amp;lt;class T, class U&amp;gt;&lt;br /&gt;  pair&amp;lt;U,U&amp;gt; operator()(pair&amp;lt;U,U&amp;gt; const &amp;amp; state, T) const {&lt;br /&gt;    return make_pair(state.second, state.first + state.second);&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So given the above implementation, the first (or left) parameter to the call to the fibonacci_folder function object is a pair which we can call the state object. This state object carries two values which are the 'previous' and 'current' value in the computation being used by the fibonacci fold. The second parameter though is ignored in this computation.&lt;br /&gt;&lt;br /&gt;If we can visualize it somehow, we can start with just two numbers (0,1). As we call fibonacci_folder()( (0,1), ignored ), it will return a pair (1, 1). The next call will become then fibonacci_folder()( (1,1), ignored ), and yield (1, 2). You can continue this as long as we're iterating.&lt;br /&gt;&lt;br /&gt;Next thing we need to do is setup our boundary iterators. If you notice, accumulate requires that you have forward iterators as the first two arguments giving the bounds upon which the function F(accumulated, *iterator) where F is the function object, accumulated is the state, and iterator is a forward iterator. We can do this simply with a Boost.Iterator called a counting_iterator&amp;lt;T&amp;gt; which simply yields a value of type T. We can then see that we can set up the left fold using accumulate with the fibonacci_folder this way:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;unsigned long fib(int n) {&lt;br /&gt;  return accumulate(&lt;br /&gt;    make_counting_iterator(0),&lt;br /&gt;    make_counting_iterator(n),&lt;br /&gt;    make_pair(0uL,1uL),&lt;br /&gt;    fibonacci_folder()&lt;br /&gt;    ).second; // we want the "current" value in the state&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This now allows us to compute the nth fibonacci number in linear time using a left fold implementation.&lt;br /&gt;&lt;br /&gt;Do you know any other interesting algorithms that are effectively converted to and are more efficient as folds instead of recursive or simply loop-based implementations? Do you think writing in this style is more elegant than simply using imperative programming principles?&lt;br /&gt;&lt;br /&gt;I'd love to know what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2360663411940452937?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UQe8aT66K6w:QxreZbqbVcI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UQe8aT66K6w:QxreZbqbVcI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UQe8aT66K6w:QxreZbqbVcI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UQe8aT66K6w:QxreZbqbVcI:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?i=UQe8aT66K6w:QxreZbqbVcI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CppSoup?a=UQe8aT66K6w:QxreZbqbVcI:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CppSoup?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/UQe8aT66K6w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2360663411940452937/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2360663411940452937" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2360663411940452937" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2360663411940452937" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/UQe8aT66K6w/fp-and-c-left-fold-fibonacci.html" title="FP and C++: A Left Fold Fibonacci Implementation" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/03/fp-and-c-left-fold-fibonacci.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-406465868632197881</id><published>2009-02-16T00:22:00.000-08:00</published><updated>2009-02-16T00:45:51.869-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="announcement" /><category scheme="http://www.blogger.com/atom/ns#" term="project" /><title type="text">Alternate Data Stream</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7Z0GWg2EV_o7n6dbRChfcJzAFao/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7Z0GWg2EV_o7n6dbRChfcJzAFao/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7Z0GWg2EV_o7n6dbRChfcJzAFao/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7Z0GWg2EV_o7n6dbRChfcJzAFao/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;So recently I've been involved with quite a number of little projects (personal and tech related) that I would like to share with the readers of this blog. First, a backgrounder on the situation.&lt;br /&gt;&lt;br /&gt;I've always been thinking about revamping the C++ Soup blog and adding more content in the form of audio/video and maybe hosting a forum of sorts. In the quest to get this process moving, I tried out &lt;a href="http://www.squarespace.com/"&gt;Square Space&lt;/a&gt; which provides a nice interface for creating your own website without having to write a single piece of code. So far, my experiments have yielded the move of my personal blog to a new domain (&lt;a href="http://deanberris.com/"&gt;deanberris.com&lt;/a&gt;) and a new host.&lt;br /&gt;&lt;br /&gt;In that process, I would like to open up the topic to you and ask what would you like to see more of from C++ Soup. I have my own list of things I'd like to put up which I'm listing down here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A weekly/monthly podcast of interesting C++ discussions -- featuring book and library authors.&lt;/li&gt;&lt;li&gt;An FAQ section with specific tutorials dedicated to specific topics -- specifically I plan to collect idioms and good ideas/snippets separated out from the blog posts.&lt;/li&gt;&lt;li&gt;Industry news and opinion articles -- news specific to C++ and related technologies like parallel high performance computing, gaming, etc.&lt;/li&gt;&lt;li&gt;More authors and contributors -- I may be opening up C++ soup to accept outside contributors and other authors to contribute fresh content to the site.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;With regard to a podcast, I recently took part in the pilot episode of the &lt;a href="http://pinoytechpodcast.blogspot.com/"&gt;Pinoy Tech Podcast&lt;/a&gt;* featuring some prominent Internet figures from the Philippines (namely &lt;a href="http://gotangco.blogspot.com/"&gt;Jerome Gotangco&lt;/a&gt;, &lt;a href="http://www.paraz.com/"&gt;Miguel Paraz&lt;/a&gt;, &lt;a href="http://blog.kapenilattex.com/"&gt;Jon Limjap&lt;/a&gt;, and &lt;a href="http://sites.google.com/a/aileenapolo.com/about-me/Home"&gt;Aileen Apolo&lt;/a&gt;). I felt really confident about being part in one that I'm seriously considering making it part of my regular internet activities -- and maybe developing a C++-centric podcast of my own. Hopefully I can get that started sooner than later.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;* NOTE: &lt;/span&gt;The podcast uses some Tagalog language in the discussion, although most of the discussion is spoken in English.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I would like to know what you think about the plans -- please feel free to post comments so that I can consider what you think. If you prefer email, you can send them to &lt;a href="mailto:dean.berris@cplusplus-soup.com"&gt;dean.berris@cplusplus-soup.com&lt;/a&gt; or &lt;a href="mailto:me@deanberris.com"&gt;me@deanberris.com&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Update:&lt;/span&gt; Adding tags to the post.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-406465868632197881?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=GHfuyjX4"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Ds1uv7I1"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ozIMoOOg"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=WnI9eAn3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=CDH11441"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=CDH11441" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=tEkybjIM"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=tEkybjIM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=iTIJIPBx"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Dc2VLd8Q"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Dc2VLd8Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=J57mYkl7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=CQPqNvc7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=CQPqNvc7" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3XNi4zJr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=PUGLIl78"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=PUGLIl78" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=7CIgKzUW"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=XcY8o4rb"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=KvziBQLC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/2YypCWYwd2M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/406465868632197881/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=406465868632197881" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/406465868632197881" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/406465868632197881" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/2YypCWYwd2M/alternate-data-stream.html" title="Alternate Data Stream" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/02/alternate-data-stream.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-2831484601606765038</id><published>2009-02-11T18:42:00.000-08:00</published><updated>2009-02-11T21:13:43.504-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="insights" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Auto-Vectorization and C++</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/a_NOfewuFqf1d9iqLbrTcTSr3XI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a_NOfewuFqf1d9iqLbrTcTSr3XI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/a_NOfewuFqf1d9iqLbrTcTSr3XI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a_NOfewuFqf1d9iqLbrTcTSr3XI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;It's been a while since I last wrote about parallel programming and C++ and recently I've been really seeing quite a lot of articles about the subject. As the days pass by it seems that C++ becomes more and more relevant in the multi-core and parallel computing/programming scene and with the upcoming new standard the renewed interest in the subject is more visible even in online discussion.&lt;br /&gt;&lt;br /&gt;Today, I just saw in my reading list an &lt;a href="http://www.ddj.com/213403518"&gt;article on auto-vectorization&lt;/a&gt; posted on &lt;a href="http://www.ddj.com"&gt;Dr. Dobb's Journal&lt;/a&gt; that's available in the recent &lt;a href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/index.htm"&gt;Intel C++ Compilers&lt;/a&gt;. It's interesting that there apparently are quite a lot of things the compiler can do for you in between making sure that your code is syntactically correct and translating it to machine code.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The Intel compiler has a feature that can make some applications run much faster -- auto-vectorisation. With a flick of the switch, some code can be sped up significantly. A number of times I have seen programs run much faster just by using this option without changing a line of code. With vectorisation, the compiler uses a set of advanced Single Instruction Multiple Data (SIMD) instructions, which ornate most modern CPUs.&lt;br /&gt;&lt;br /&gt;from &lt;a href="http://www.ddj.com/213403518"&gt;"I've Fallen In Love With the Vectoriser"&lt;/a&gt;.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I personally can vouch for the effectiveness of leveraging the processor's performance in mission critical performance-sensitive applications. I however had been using the tree vectorization optimization that's been present in the &lt;a href="http://gcc.gnu.org/"&gt;GCC&lt;/a&gt; compiler since version &lt;a href="http://gcc.gnu.org/gcc-4.1/changes.html"&gt;4.1.x&lt;/a&gt; (through the -ftree-vectorize option).&lt;br /&gt;&lt;br /&gt;Vectorization talks about the technique of transforming code to work in a &lt;a href="http://en.wikipedia.org/wiki/Vector_processor"&gt;vector processor&lt;/a&gt; -- that is, processor that can perform a single instruction on multiple data (&lt;a href="http://en.wikipedia.org/wiki/SIMD"&gt;SIMD&lt;/a&gt;) and hence the root of the SSE instruction set (SSE stands for &lt;a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions"&gt;Streaming SIMD Extensions&lt;/a&gt;). This makes repetitive mathematical instructions that can be performed in parallel to be done in fewer instructions than it would normally take if they were done in sequence.&lt;br /&gt;&lt;br /&gt;To those that have read about parallel computing in the early days (around the '70s or '80s) will know that there has been a wealth of research dealing with how to do parallel programming in many different types of computers. Recently, these techniques seem to be coming up again in the midst of the move to parallel programming -- and this is to no surprise. Apparently the evolution from sequential processors (&lt;a href="http://en.wikipedia.org/wiki/Von_Neumann_architecture"&gt;Von Neumann architecture&lt;/a&gt;) to parallel processors (&lt;a href="http://en.wikipedia.org/wiki/Systolic_array"&gt;systolic arrays&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Hypercube"&gt;hypercubes&lt;/a&gt;, and &lt;a href="http://en.wikipedia.org/wiki/Mesh_networking"&gt;meshes&lt;/a&gt;) translate to even the commodity processors of today.&lt;br /&gt;&lt;br /&gt;Let's take the vector processors: it might be a surprise to some to find out that the &lt;a href="http://en.wikipedia.org/wiki/Graphics_processing_unit"&gt;GPU&lt;/a&gt;s in the modern day graphics cards are actually SIMD processors and that it leverages research that has been done on the parallel computing field. This is the reason why it can perform blazingly fast computations on the fly to generate life-like 3D images at high frame rates. This is also the same reason why the cheapest way to get your hands on a supercomputer today to perform repetitive mathematical computations on large data sets is to get a handful of these GPUs together and program to utilize these processors.&lt;br /&gt;&lt;br /&gt;Because of the popularity of these SIMD instruction sets, the modern day multi-core processors actually have a small vector processor embedded that knows how to do practically the same thing albeit at a smaller scale. Actually, this trend has started earlier in the higher performance single-core processors (as early as Pentium III). The first application was for improving processor performance for games that require these sorts of instructions to make certain things feasible.&lt;br /&gt;&lt;br /&gt;In the case of the hypercube architecture, you can look at the modern day multi-core processor as a simple case of a 1-dimensional hypercube of processors (dual core) or 2-dimensional hypercube of processors (quad core). In the early days of the hypercube architecture, each processor had dedicated communication channels to each other and did not share data. Today, you can look at multi-core processors as an evolution of this early-day hypercube architecture but with a shared memory space. Starting with the current and next generation many-core processors though, you'll see &lt;a href="http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access"&gt;NUMA&lt;/a&gt; and have each processor be responsible for managing certain memory modules.&lt;br /&gt;&lt;br /&gt;This is all interesting from the hardware architectural perspective, but how does it concern C++? For instance the compilers which have greater insight into the target architecture of the machine on which you'll be running your code will be able to leverage the available instruction sets and generate more efficient code. Knowing the architecture of the processors will also give programmers greater insights about how to leverage the available cache, layout, and memory management characteristics of the system to write effective high-level code in a guided and informed manner. Certain decisions and predictions can be made through deliberate examination of the available technology and tools at your disposal as a C++ programmer (threads, synchronization primitives, memory usage, etc.).&lt;br /&gt;&lt;br /&gt;There's more to come in the coming months and years ahead as we start getting more and more immersed in the reality that multi-core and parallel programming is the future. I forget where I read/heard it before, but this is the classic case where "Resistance is Futile" would definitely apply.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-2831484601606765038?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=FEKpAMic"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=NEdUpN39"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=4Au2qYGf"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=PSKB5Htb"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=OVg2NdVo"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=OVg2NdVo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=J9PjKFYG"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=J9PjKFYG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=uowClTsC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=TEFLtvK5"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=TEFLtvK5" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=9uxSCkXw"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=fzbS84Hv"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=fzbS84Hv" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3S3hq8O8"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=AXbMegI0"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=AXbMegI0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ic97eF4w"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=qpkOABTY"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=HQh5iTDl"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/05vnWp9BPBI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/2831484601606765038/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=2831484601606765038" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2831484601606765038" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/2831484601606765038" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/05vnWp9BPBI/auto-vectorization-and-c.html" title="Auto-Vectorization and C++" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/02/auto-vectorization-and-c.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-3642180608221098161</id><published>2009-02-01T09:42:00.000-08:00</published><updated>2009-02-01T10:47:13.572-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="review" /><title type="text">Programming: Principles and Practice Using C++</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ScwXPieX4Hb4BQn8JYVcb0Hqfww/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ScwXPieX4Hb4BQn8JYVcb0Hqfww/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ScwXPieX4Hb4BQn8JYVcb0Hqfww/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ScwXPieX4Hb4BQn8JYVcb0Hqfww/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I&amp;#8217;ve been lucky enough to be contacted by Pearson Education (Addison-Wesley) and given a review copy of &lt;a href="http://en.wikipedia.org/wiki/Bjarne_Stroustrup"&gt;Bjarne Stroustrup&amp;#8217;s&lt;/a&gt; latest book titled &lt;a href="http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726"&gt;Programming: Principles and Practice Using C++&lt;/a&gt;. In the past few days, I&amp;#8217;ve been reading this book of considerable size chock full of knowledge poured out directly by the creator of C++ himself.&lt;/p&gt;&lt;p&gt;If you haven&amp;#8217;t read a book by Bjarne yet be prepared to be treated to well-thought out examples and a very expressive presentation of concepts and techniques. The book is an easy read especially if you&amp;#8217;re new to programming and want to really learn how to think like a programmer. The overall presentation approach that the book takes is very light and the exercises are aimed definitely for the novice.&lt;/p&gt;&lt;p&gt;Advanced developers will definitely gain lots of insights into how Bjarne thinks about programming&amp;#8212;and how potentially you can present programming to novices. If you&amp;#8217;re working in a team with junior developers, this book is a great addition to the library. If you&amp;#8217;re a teacher teaching introduction to programming, this is a great reference and textbook because you get to teach/learn programming with a considerably powerful real world programming language.&lt;/p&gt;&lt;p&gt;The 27 chapters of the book are broken down into four logical parts. The first part is aimed at developers looking to pick up programming from the ground up dealing with foundational issues like variables, classes, functions, and programs in general. The second part is aimed at dealing with real-world issues dealing with input and output and how you can deal with the data using various constructs provided by the C++ language and libraries (like the Standard Template Library). The third part deals more specifically with issues of working with the Standard Template Library in greater detail particularly with the data structures and algorithms. Part four is a survey of the kinds of things you&amp;#8217;ll be encountering when you go into professional programming&amp;#8212;as well as one chapter on the relationship between C and C++.&lt;/p&gt;&lt;p&gt;I particularly like the way Bjarne adresses the reader as an active participant in the learning process. He puts in as much detail as he can without belaboring a point too much. His examples are interesting and representative of the kinds of challenges programmers will be facing in the real world but not too complex to be a hindrance to the learning.&lt;/p&gt;&lt;p&gt;This is the book I wish I read while I was in college studying computer science&amp;#8212;and this is a book I will really recommend to educators and students alike looking for a good foundation book on programming and C++. If you&amp;#8217;re thinking of learning C++ from scratch, invest in this book and I guarantee you will not be disappointed. If you&amp;#8217;re a freshman or sophomore in college looking to a career in programming after college, pick up this book and I assure you that you will learn many gems from this book.&lt;/p&gt;&lt;p&gt;I definitely think the industry is in need of a good book on the &amp;#8220;how-to&amp;#8221; of programming using a powerful real world language&amp;#8212;and &lt;a href="http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726"&gt;Programming: Principles and Practice Using C++&lt;/a&gt; can definitely be that book.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-3642180608221098161?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=1ptLd4tC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ASUF3dG6"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Xs3Twxpe"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=bZGM0SDy"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=6isCrt7W"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=6isCrt7W" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=l5oQN0mE"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=l5oQN0mE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=yBkqqc6S"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=qiBiTOek"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=qiBiTOek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=NMaSKBw1"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wq9BzqQ8"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=wq9BzqQ8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=rlJ7QPiw"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=4byyOcAt"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=4byyOcAt" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=dcnHGsIc"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=2nOroXTG"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3jBnNrC5"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/Js834xFTBE4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/3642180608221098161/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=3642180608221098161" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/3642180608221098161" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/3642180608221098161" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/Js834xFTBE4/programming-principles-and-practice.html" title="Programming: Principles and Practice Using C++" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/02/programming-principles-and-practice.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-4630819032257987246</id><published>2009-01-15T00:22:00.000-08:00</published><updated>2009-01-15T01:06:36.953-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="thoughts" /><category scheme="http://www.blogger.com/atom/ns#" term="insights" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Parallel Computing: Microsoft or Intel</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Vv7WxroACmXkvZ20BWxQ9F5B-_0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Vv7WxroACmXkvZ20BWxQ9F5B-_0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Vv7WxroACmXkvZ20BWxQ9F5B-_0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Vv7WxroACmXkvZ20BWxQ9F5B-_0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Until recently, I personally didn't give &lt;a href="http://microsoft.com/"&gt;Microsoft (R)&lt;/a&gt; much props for parallel computing research and development. I always equated their efforts in the developer community to desktop development productivity tools (which are top notch by the way) and considerably "unreliable" products (like Vista).&lt;br /&gt;&lt;br /&gt;However nowadays it seems like they are becoming really serious with dealing with the multi-core and concurrent development movement. I see lots of room for improvement, but I think I would be convinced finally when Visual Studio 2010 with better C++0x support and better concurrent programming tools come from their well-guarded gates. Some of the evidence that's starting to sway me towards giving big MS more credit is shown in the smart and insightful discussion between hotshots from within Microsoft in this Channel 9 video by &lt;a href="http://channel9.msdn.com/Niners/Charles/"&gt;Charles&lt;/a&gt; on &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Parallel-Computing-in-Native-Code-New-Trends-and-Old-Friends/"&gt;Parallel Computing in Native Code: New Trends and Old Friends&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I personally give &lt;a href="http://intel.com/"&gt;Intel&lt;/a&gt; a lot more credit for their &lt;a href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/284132.htm"&gt;superior C++ compilers&lt;/a&gt; for their platform and the widely-accepted (not to mention Open Source) &lt;a href="http://www.threadingbuildingblocks.org/"&gt;Threading Building Blocks&lt;/a&gt;. In a recent &lt;a href="http://software.intel.com/en-us/blogs/2009/01/14/opensolaris-and-nehalem-a-digital-short/"&gt;video about OpenSolaris and Core i7&lt;/a&gt;, I see Intel really playing well with the open source community by doing lots for the &lt;a href="http://opensolaris.org/"&gt;OpenSolaris&lt;/a&gt; operating system and making it work better for the Core i7 (codename Nehalem) micro-architecture.&lt;br /&gt;&lt;br /&gt;Looking at the situation as a semi-outsider, I think how Microsoft and Intel are playing the industry is very complementary -- Microsoft has great tools for developing software for their platform that work on Intel's hardware while Intel works with Microsoft by making sure Windows works well on Intel hardware. It's hard to miss how these two big players in C++ will definitely shape how the future of programming will look like especially with a new low-level architecture and better-looking and productivity-enhancing tools.&lt;br /&gt;&lt;br /&gt;Now what about the competition? &lt;a href="http://sun.com/"&gt;Sun&lt;/a&gt;'s play into the High Performance Computing and &lt;a href="http://www.sun.com/solutions/cloudcomputing/index.jsp"&gt;Cloud Computing&lt;/a&gt; market is showing how they want to play at a higher level than low-level concurrency and better developer tools. Although I know Sun has been offering x86-based servers, I still think their focus on a higher level is both good and bad. Good because they're trying to take a foothold in a vigorously emerging sector of the industry. Bad because that means they might be relying on other people's efforts (Intel and the open source community) to advance technology.&lt;br /&gt;&lt;br /&gt;At any rate I see big blue &lt;a href="http://ibm.com/"&gt;IBM&lt;/a&gt; being the most to gain in the field -- their mix of research and development for hardware and years worth of expertise in the consulting business is like a good 1-2 punch for staying relevant in any market. So while I see Microsoft and Intel pushing the envelope with C++ and parallel computing, I see lots of other people and companies getting most of the benefit.&lt;br /&gt;&lt;br /&gt;Maybe someday I can get in on the action too providing much a crucial service to those who need it. But that's not in my horizon yet as far as I can tell.&lt;br /&gt;&lt;br /&gt;What do you think about the current software and hardware movement towards parallelism?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-4630819032257987246?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=XhORvR5p"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=CzQXQqFZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=fy9l6PZN"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ATJmFxKu"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=TZmcvNiU"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=TZmcvNiU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=11JparQT"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=11JparQT" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=yFussqp3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=9SUlgYWk"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=9SUlgYWk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=I6ifzmbr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=xMkyANa5"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=xMkyANa5" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3fMtmVpY"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=R8mI9gyt"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=R8mI9gyt" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3qQwRc0m"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=JnSkqRVW"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=fLxGAChA"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/SzxxD7tjtek" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/4630819032257987246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=4630819032257987246" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4630819032257987246" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4630819032257987246" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/SzxxD7tjtek/parallel-computing-microsoft-or-intel.html" title="Parallel Computing: Microsoft or Intel" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/01/parallel-computing-microsoft-or-intel.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-6646640546945405488</id><published>2009-01-13T01:00:00.001-08:00</published><updated>2009-01-13T01:21:12.954-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="thoughts" /><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="insights" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">C++0x Atomics and Concurrency Woes</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Q-Z_O9RlmMdS1jHcIwygM8gNFEE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Q-Z_O9RlmMdS1jHcIwygM8gNFEE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Q-Z_O9RlmMdS1jHcIwygM8gNFEE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Q-Z_O9RlmMdS1jHcIwygM8gNFEE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;If you've been through Java programming before, you'd know that one of the nice features would be the clear semantics for concurrency of the volatile keyword. If you wanted to say that a variable may change at any given time but be assured that changes to it would be atomic, you'd name it volatile. Not only that, if you wanted to make sure a method was executed atomically within the virtual machine, you'd mark it synchronized.&lt;br /&gt;&lt;br /&gt;Until recently C++ lacks a volatile keyword that makes variables behave like atomic variables. The C++ volatile keyword is a directive to the compiler that says "hey, you can't assume anything about the storage/location of this variable -- so don't try and deduce and optimize away changes to this one". &lt;a href="http://herbsutter.wordpress.com/"&gt;Herb Sutter&lt;/a&gt; has recently posted a summary of the explanation to the C++0x standard atomic template in his latest installment titled aptly &lt;a href="http://www.ddj.com/hpc-high-performance-computing/212701484"&gt;"volatile vs. volatile"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you look at illustrated table &lt;a href="http://i.cmpnet.com/ddj/images/article/2009/0901/090108sutter_t1.gif"&gt;comparison between the semantics of Java/.NET's volatile keyword and C++'s volatile keyword&lt;/a&gt; it would be easy to see why people (like me included) are usually confused with what "volatile" is really about. Thankfully, C++0x has the atomic template to give us C++ developers the capability to use the same volatile semantics protecting types from unsynchronized access. Not only does this allow people to write essentially lock-free (in the normal sense using considerably heavy-weight mutexes) code and get the performance benefits of being really close to the metal.&lt;br /&gt;&lt;br /&gt;Much is to be said about the upcoming C++0x implementation and what's really exciting for me are the concurrency-specific changes to be made part of the language and the standardization of libraries pertaining to concurrency -- threading, futures, among many other things. Right now it's a waiting game to find out who among the many vendors out there will be able to come up with reasonably compliant C++0x compilers first, and I for one am going to be trying out the new features of &lt;a href="http://gcc.gnu.org/gcc-4.3/"&gt;GCC 4.3.x&lt;/a&gt; to get a feel for C++0x for myself.&lt;br /&gt;&lt;br /&gt;In your case, how will the next C++ standard affect the way you do concurrency-aware programming? Do you think the new features will really be helpful or do you think there are still many things lacking? I'd love to hear what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-6646640546945405488?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=G5ZDcmBC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=m5UpqCli"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=zy815RFv"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=75SyOhB7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Mcb7vLiv"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Mcb7vLiv" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=7qOLdugZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=7qOLdugZ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3O0GgD10"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=etLkJTHE"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=etLkJTHE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=BHPXNioc"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=TXutH9J7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=TXutH9J7" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=vlffz6jX"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=vVWUDSzS"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=vVWUDSzS" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=0oTwTUNs"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wXCFSHI3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ZAZLEvK6"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/CTmqkRwjWA8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/6646640546945405488/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=6646640546945405488" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6646640546945405488" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6646640546945405488" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/CTmqkRwjWA8/c0x-atomics-and-concurrency-woes.html" title="C++0x Atomics and Concurrency Woes" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/01/c0x-atomics-and-concurrency-woes.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-962387861578395636</id><published>2009-01-10T22:14:00.000-08:00</published><updated>2009-01-10T22:26:29.548-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="library" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">C++0x Threading Library Released</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/V7IysxnWAlsGULJRpRnT85hWT7Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V7IysxnWAlsGULJRpRnT85hWT7Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/V7IysxnWAlsGULJRpRnT85hWT7Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V7IysxnWAlsGULJRpRnT85hWT7Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently, &lt;a href="http://www.justsoftwaresolutions.co.uk/"&gt;Anthony Williams&lt;/a&gt; (author of &lt;a href="http://www.manning.com/williams/"&gt;C++ Concurrency in Action&lt;/a&gt; which I also &lt;a href="http://blog.cplusplus-soup.com/2008/11/c-concurrency-in-action-preview.html"&gt;reviewed&lt;/a&gt; recently) has recently released version 1.0 of his threading library that is C++0x compliant.&lt;br /&gt;&lt;br /&gt;From his blog post about the release, the following is just a list of features available from the library:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The just::thread library is a complete implementation of the new C++0x thread library as per the current C++0x working paper. Features include:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;std::thread for launching threads.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mutexes and condition variables.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;std::promise, std::packaged_task, std::unique_future and std::shared_future for transferring data between threads.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for the new std::chrono time interface for sleeping and timeouts on locks and waits.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Atomic operations with std::atomic.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for std::exception_ptr for transferring exceptions between threads.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Special deadlock-detection mode for tracking down the call-stack leading to deadlocks, the bane of multithreaded programming.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The library works with Microsoft Visual Studio 2008 or Microsoft Visual C++ 2008 Express for 32-bit Windows.&lt;br /&gt;&lt;br /&gt;from &lt;a href="http://www.justsoftwaresolutions.co.uk/news/just_thread_C++0x_thread_library_v1.0_released.html"&gt;just::thread C++0x Thread Library V1.0 Released&lt;/a&gt;.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I'm not sure whether this will be also ported to become Boost.Thread (which Antony also maintains) but I do know that there are currently two versions of a futures library implementation that's ongoing in the Boost C++ Developers Mailing list.&lt;br /&gt;&lt;br /&gt;You can get your copy of just::thread commercially from &lt;a href="http://www.stdthread.co.uk/order.html"&gt;the order site&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-962387861578395636?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Oo1PhCqN"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ObzVQgz5"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Y3MxqMZq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=e3Fk7Hzd"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=dwC86Q92"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=dwC86Q92" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Nyk3VXeu"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Nyk3VXeu" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=duySkyNZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=SZgLK3mO"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=SZgLK3mO" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=7XfYfzP3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=N27U0bu1"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=N27U0bu1" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=h5xwVEJ3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=a5evpZoQ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=a5evpZoQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=aZiQIqcC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=IvdtovAq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=xTMSSWmr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/zFUFcF8zqpI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/962387861578395636/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=962387861578395636" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/962387861578395636" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/962387861578395636" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/zFUFcF8zqpI/c0x-threading-library-released.html" title="C++0x Threading Library Released" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2009/01/c0x-threading-library-released.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-4458912742143026808</id><published>2008-12-26T11:32:00.000-08:00</published><updated>2008-12-26T11:34:18.335-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="announcement" /><title type="text">Holiday Greetings</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/58UNP915NA1T1bTRwbCkWYikcoE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/58UNP915NA1T1bTRwbCkWYikcoE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/58UNP915NA1T1bTRwbCkWYikcoE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/58UNP915NA1T1bTRwbCkWYikcoE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I know it's already days past but I just want to wish everyone subscribed to and following the blog "Happy Holidays!".&lt;br /&gt;&lt;br /&gt;I'm looking forward to a productive and very interesting 2009!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-4458912742143026808?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=4N35TI9H"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=aQeY4dEl"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wUoSRSLS"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=cCgc7bGY"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=0pIrx8C9"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=0pIrx8C9" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=x6cdGrHN"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=x6cdGrHN" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=aLnNdYpc"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=xPbj2YoO"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=xPbj2YoO" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wTefUadb"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=N1oo5DDD"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=N1oo5DDD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=gL05S6m7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=nCSJQaQK"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=nCSJQaQK" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=IzSZcJEx"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=TpiodDhp"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=DrP8d6B9"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/pucIrhWzZU8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/4458912742143026808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=4458912742143026808" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4458912742143026808" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4458912742143026808" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/pucIrhWzZU8/holiday-greetings.html" title="Holiday Greetings" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/12/holiday-greetings.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-7340821128934665828</id><published>2008-12-12T02:59:00.000-08:00</published><updated>2008-12-12T03:24:33.771-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Windows 7 : A Game Changer?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3s3CObBtD_0EP1vtS7yo_l-3Zt4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3s3CObBtD_0EP1vtS7yo_l-3Zt4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3s3CObBtD_0EP1vtS7yo_l-3Zt4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3s3CObBtD_0EP1vtS7yo_l-3Zt4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://software.intel.com/en-us/blogs/2008/12/11/extreme-parallelism-with-windows-7/"&gt;Doug Holland (Intel)&lt;/a&gt; posted a coverage of this &lt;a href="http://channel9.msdn.com"&gt;Channel 9&lt;/a&gt; talk about the upcoming &lt;a href="http://www.microsoft.com/windows/windows-7/"&gt;Windows 7&lt;/a&gt; operating system. I personally am not a big &lt;a href="http://microsoft.com"&gt;Microsoft&lt;/a&gt; fan, but I appreciate that the company is still focused on the goal of delivering innovative and (arguably) technically superior products. &lt;a href="http://blogs.technet.com/markrussinovich/default.aspx"&gt;Mark Russionovich&lt;/a&gt; was interviewed by "&lt;a href="http://carmine.blogs.com/"&gt;Charles&lt;/a&gt;" on Channel 9, and here's an excerpt on the details of the discussion:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;... One very important change in the Windows 7 kernel is the dismantling of the dispatcher spin lock and redesign and implementation of its functionality. This great work was done by Arun Kishan (&lt;a href="http://channel9.msdn.com/shows/Going+Deep/Arun-Kishan-Process-Management-in-Windows-Vista/"&gt;you've met him here on C9 last year&lt;/a&gt;). The direct result of the reworking of the dispatcher spin lock is that Windows 7 can scale to 256 processors. Further, this enabled &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Landy-Wang-Windows-Memory-Manager/"&gt;the great Landy Wang&lt;/a&gt; to tune the Windows Memory Manager to be even more efficient than it already is. ...&lt;br /&gt;&lt;br /&gt;from &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Mark-Russinovich-Inside-Windows-7/"&gt;Going Deep &amp;gt; Mark Russinovich: Inside Windows 7&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;While watching the video it's amazing how forthcoming and how much detailed that kernel architect of Windows is willing to go regarding the development process and the changes that were made. I wouldn't have expected this sort of openness from an employee of a company started by Bill Gates who practically made sure things in Microsoft were kept proprietary.&lt;br /&gt;&lt;br /&gt;Enough about that commentary, the technical details are very interesting indeed. It makes me think about how I approach the operating system kernel when I write multi-threaded applications. Although I don't program on the Windows platform I see how changes in the Operating Systems will definitely play a bigger role in the future when people get their hands on machines with many cores available.&lt;br /&gt;&lt;br /&gt;I definitely look foward to having the equivalent of "user mode scheduling" in Linux or if just something emulated to have work-stealing wait()'s to maximize thread time slices and minimize waiting on highly concurrent applications. Server applications running on the Windows platform will definitely get a big boost just from the description of what the changes in store for Windows 7 when it does come out.&lt;br /&gt;&lt;br /&gt;Does anybody know if there's something similar happening in the Linux kernel space?&lt;br /&gt;&lt;br /&gt;Update: Added missing link to reference article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-7340821128934665828?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=aQWriJmz"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=1lwwvD7k"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=sJenP61f"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wqt1mjHB"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Rps3piCs"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Rps3piCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=b5fOPe2z"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=b5fOPe2z" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Q5CIEkeZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ISt4GWoW"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=ISt4GWoW" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=5RYQom2k"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=lnO9P0Q2"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=lnO9P0Q2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=AbSSUhDr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=cXDIoTHW"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=cXDIoTHW" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=O54lJWXA"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=heRA4SUr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=O6nNAM3q"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/lMuujVoYzIE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/7340821128934665828/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=7340821128934665828" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7340821128934665828" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7340821128934665828" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/lMuujVoYzIE/windows-7-game-changer.html" title="Windows 7 : A Game Changer?" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/12/windows-7-game-changer.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-5263673787367562357</id><published>2008-12-09T21:31:00.000-08:00</published><updated>2008-12-09T21:55:59.746-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">OpenCL : Shifting Tides</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GPsM3E32phLpMyMRxio34bN0urQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GPsM3E32phLpMyMRxio34bN0urQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GPsM3E32phLpMyMRxio34bN0urQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GPsM3E32phLpMyMRxio34bN0urQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;While going through my reading list, I came across a &lt;a href="http://www.ddj.com/hpc-high-performance-computing/212300363"&gt;news article&lt;/a&gt; from &lt;a href="http://www.ddj.com/"&gt;Dr. Dobb's Journal&lt;/a&gt; about the release of the &lt;a href="http://www.khronos.org/registry/cl/specs/opencl-1.0.29.pdf"&gt;OpenCL 1.0 specifications&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;From the &lt;a href="http://www.khronos.org/opencl/"&gt;Khronos Group article&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;OpenCL supports a wide range of applications, from embedded and consumer software to HPC solutions, through a low-level, high-performance, portable abstraction. By creating an efficient, close-to-the-metal programming interface, OpenCL will form the foundation layer of a parallel computing ecosystem of platform-independent tools, middleware and applications.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;What we can look forward to given this release is the boom of parallel-aware compilers which are not only able to do auto-vectorization to leverage the &lt;a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions"&gt;Streaming SIMD extensions&lt;/a&gt; available in both (modern) &lt;a href="http://intel.com"&gt;Intel&lt;/a&gt; and &lt;a href="http://amd.com"&gt;AMD&lt;/a&gt; processors. We also may be able to see better performance from TR2-slated libraries for parallel counterparts to the STL algorithms.&lt;br /&gt;&lt;br /&gt;This release of OpenCL is very significant since most of the major hardware and software vendors are part of the group that developed the specifications. This means one day (in the not so distant future) hardware vendors that support OpenCL on their devices will be able to run applications that depend on the OpenCL spec -- imagine your 4-core-8-thread-capable application will be able to seamlessly scale to 32-core-128-thread machines. We'll also start seeing compilers which will be able to leverage the OpenCL specifications to create binaries that take advantage of OpenCL aware architectures.&lt;br /&gt;&lt;br /&gt;It has been noted that &lt;a href="http://apple.com/"&gt;Apple&lt;/a&gt; is a driver in this space. I just wonder though how the &lt;a href="http://llvm.org/"&gt;LLVM&lt;/a&gt; development happening in Apple has anything to do with their wanting to develop an open standard for leveraging parallel computing systems. At any rate, with a slowly-but-surely maturing &lt;a href="http://clang.llvm.org/"&gt;Clang&lt;/a&gt; frontend to an LLVM compiler, a growing set of literature and implementations on &lt;a href="http://en.wikipedia.org/wiki/Automatic_vectorization"&gt;automatic vectorization&lt;/a&gt; of code in C++ compilers, it's just evidence that we should really start paying attention to the parallel computing space if we want to remain relevant.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; Adding links to SSE extensions definition and Intel (R) /AMD (R).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-5263673787367562357?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=67Xez3Gj"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=J6lc9oJ2"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=pLrumbYk"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=mfWnnXRS"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=8wmm33xq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=8wmm33xq" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=kz4c0RvN"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=kz4c0RvN" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=bxbrTB7X"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Ge76e0ro"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Ge76e0ro" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=OaS3dVaq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Z1zUtJQV"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Z1zUtJQV" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Sm394UKq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=L6952fNs"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=L6952fNs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=uxmkreck"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=iwPdhOGs"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=JwvBHFiq"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/JGdPxisbpm0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/5263673787367562357/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=5263673787367562357" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/5263673787367562357" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/5263673787367562357" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/JGdPxisbpm0/opencl-shifting-tides.html" title="OpenCL : Shifting Tides" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/12/opencl-shifting-tides.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-4249236872119042611</id><published>2008-12-03T06:25:00.000-08:00</published><updated>2008-12-03T06:44:44.670-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="thoughts" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">The Optimization Game</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3W8nZwW1zNg5hysCcK0HXeeswOo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3W8nZwW1zNg5hysCcK0HXeeswOo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3W8nZwW1zNg5hysCcK0HXeeswOo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3W8nZwW1zNg5hysCcK0HXeeswOo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://gotw.ca/"&gt;Herb Sutter&lt;/a&gt; has written recently about &lt;a href="http://www.ddj.com/hpc-high-performance-computing/212201163"&gt;optimizing parallel performance of a concurrent queue&lt;/a&gt; as part of his ongoing series of articles about concurrency and parallel programming. In his article, he shows how you can empirically test the performance of a parallel component (in this case, a concurrent queue) and then adjust the implementation to maximize the available parallelism from the solution.&lt;br /&gt;&lt;blockquote&gt;How would you write a fast, internally synchronized queue, one that callers can use without any explicit external locking or other synchronization? Let us count the ways...or four of them, at least, and compare their performance. We'll start with a baseline program and then successively apply three optimization techniques, each time stopping to measure each change's relative performance for queue items of different sizes to see how much each trick really bought us.&lt;br /&gt;&lt;br /&gt;from &lt;a href="http://www.ddj.com/hpc-high-performance-computing/212201163"&gt;Measuring Parallel Performance: Optimizing a Concurrent Queue&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I haven't finished reading through the article yet but I definitely think this is going to be another good read. He mentions the necessity of really avoiding races at any cost (as far as using spinlocks on a supposedly lock-free concurrent queue implementation through atomics) and I for one agree that in the interest of stability and correctness, there are some concessions that have to be made.&lt;br /&gt;&lt;br /&gt;One other thing that he follows very prudently is the carpenter's advice which is: measure twice, cut once. He doesn't just go blindly guessing where and how performance improvements can be gained in the implementation, but rather use measurements and small incremental changes and sees what kind of performance gains are made.&lt;br /&gt;&lt;br /&gt;More about my thoughts on the article in the coming post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-4249236872119042611?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=anqfTyxJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=8QGqoeJ6"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=QCNDVudy"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ZLR6mnI7"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=PVxqIcJr"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=PVxqIcJr" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Ro8pJl0R"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Ro8pJl0R" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=EaV6EYiU"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=fnmgZEpF"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=fnmgZEpF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=DtxBynTC"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=figzNOht"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=figzNOht" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=BRkKDvrj"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=VX1WE7VE"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=VX1WE7VE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=KK0T1T6H"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=JTI6cB32"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=QS2MZwvi"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/yxaIVTir_sY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/4249236872119042611/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=4249236872119042611" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4249236872119042611" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/4249236872119042611" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/yxaIVTir_sY/optimization-game.html" title="The Optimization Game" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/12/optimization-game.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-1452188537828694651</id><published>2008-11-25T06:53:00.000-08:00</published><updated>2008-11-25T07:13:11.815-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="thoughts" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Parallel Cryptography</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QVRC8p3vFfWQKi4OnNY_X42LnT4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QVRC8p3vFfWQKi4OnNY_X42LnT4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QVRC8p3vFfWQKi4OnNY_X42LnT4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QVRC8p3vFfWQKi4OnNY_X42LnT4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I was again going through my reading list (lately I've had a lot of time to catch up with my reading) and an article from Dr. Dobb's journal caught my eye: an article about a &lt;a href="http://www.ddj.com/security/212200219"&gt;parallel implementation of MD&lt;/a&gt;6. It's not really rocket science that some of these algorithms can be parallelized, but what is more important is how they did it. The following snippet doesn't do much justice to how easy possibly the future of parallel programming with C++ can be.&lt;br /&gt;&lt;blockquote&gt;The full MD6 application has over 3,000 lines of code. Adding two Cilk keywords (at the bottom of the code snippet below) was sufficient to multicore-enable the algorithm. MD6 is recursive, and adding the Cilk++ keywords exposes a great deal of parallelism.&lt;br /&gt;&lt;br /&gt;from &lt;a href="http://www.ddj.com/security/212200219"&gt;Multicore and Cryptographic Hash Functions&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;Imagine being able to multi-core enable your code with just keywords instead of thinking about how to implement/use threads and thread pools. Of course you still have to know where to introduce the parallelism, where the problem can usually be.&lt;br /&gt;&lt;br /&gt;It takes some effort in designing and implementing algorithms that will be able to take advantage of the parallelism available in the hardware and it's no joke implementing a robust cryptographic function at the same time. It's really something else when an algorithm is designed to be implemented in parallel.&lt;br /&gt;&lt;br /&gt;I would think it's just a matter of time before we start seeing more of the upcoming implementations be more parallelism aware than we currently are seeing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-1452188537828694651?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=m1FdJra0"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=n0cxydr3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=bMDalJsV"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=gYmAmUao"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=KrOPsLiy"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=KrOPsLiy" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=DlhdLRXe"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=DlhdLRXe" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=o5jztjMd"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=JxFRppZY"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=JxFRppZY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=5Z51wLRd"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=4cpcqBxG"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=4cpcqBxG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=3qQrZYoF"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=WvvNM5It"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=WvvNM5It" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=xHqm9WoG"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=UTpsn6va"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=7r6gQxk3"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/x0v-R3UU9lU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/1452188537828694651/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=1452188537828694651" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/1452188537828694651" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/1452188537828694651" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/x0v-R3UU9lU/parallel-cryptography.html" title="Parallel Cryptography" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/11/parallel-cryptography.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-7459829012966414429</id><published>2008-11-22T03:33:00.000-08:00</published><updated>2008-11-22T03:34:19.896-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cool stuff" /><category scheme="http://www.blogger.com/atom/ns#" term="thoughts" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">Diagonal Scaling?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JoC-tcYxvtlMnjZbiXsV3NXhd3E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JoC-tcYxvtlMnjZbiXsV3NXhd3E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JoC-tcYxvtlMnjZbiXsV3NXhd3E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JoC-tcYxvtlMnjZbiXsV3NXhd3E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;While reading through my reading list, I ran into this article from &lt;a href="http://cloudn.com/"&gt;CloudN&lt;/a&gt; which hit a nerve with the kinds of things I've been trying to accomplish in the day job. This pertains to scaling your infrastructure not just in a horizontal manner (scaling out, adding more machines) or just in a vertical manner (adding more power to a single processing unit), but rather in a diagonal direction:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;... we are starting to see a third general model of scaling emerging over and over again. This third model can be conveniently characterized as “scaling diagonally”. In diagonal scaling, a small fraction of the total number of servers (say 1% or 0.1%) are highly stateful and highly reliable. The other 99% or 99.9% are very low-cost (inherently unreliable) commodity machines that carry out the bulk of the work, but are not responsible for maintaining complex metadata or complex state.&lt;/p&gt;&lt;p&gt;from &lt;a href="http://cloudn.com"&gt;CloudN&lt;/a&gt; post &lt;a href="http://cloudn.com/?p=222"&gt;How to Scale? - Up, Out, or Diagonally&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This makes sense definitely since most (if not all) of the time you're constrained with a budget and a set of requirements for both performance/throughput and reliability. This model serves the requirements of a lot of massively parallel computations that have any sort of business relevance.&lt;/p&gt;&lt;p&gt;There have been a lot of similarly built architectures with C++ -- most notably &lt;a href="http://hypertable.org"&gt;Hypertable&lt;/a&gt; where you have a single name host which knows where the other range servers are and a single "lock server" (called Hyperspace) which coordinates changes across the cluster. If you haven't yet, you should read more about the &lt;a href="http://code.google.com/p/hypertable/wiki/ArchitecturalOverview"&gt;Hypertable architecture&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you're in an industry where you find yourself dealing with massive amounts of data and are required to do it in a very fast and reliable manner, you should definitely check out these newer technologies for both storing and processing your data.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-7459829012966414429?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Mxk8fcMl"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=PNMxpT2M"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=brVxrvXM"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ThxF2mVj"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=YufArimk"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=YufArimk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=jkAjKm16"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=jkAjKm16" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=zaQEkiT0"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=vBBRNh6r"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=vBBRNh6r" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=9KZoktzN"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=nEQapQSh"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=nEQapQSh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=dpVFGDu5"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=B1i0M74D"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=B1i0M74D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Id5JJzSc"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=iLwHfRRm"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=S6tWILqt"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/oAm6INF9uNQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/7459829012966414429/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=7459829012966414429" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7459829012966414429" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/7459829012966414429" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/oAm6INF9uNQ/diagonal-scaling.html" title="Diagonal Scaling?" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/11/diagonal-scaling.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-12142884.post-6872038334566010291</id><published>2008-11-21T11:37:00.000-08:00</published><updated>2008-11-21T11:40:01.142-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="insights" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel" /><title type="text">C++ Concurrency in Action - A (P)Review</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rLv8okEg78ilOpn-cFlQ-B9wQuA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rLv8okEg78ilOpn-cFlQ-B9wQuA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rLv8okEg78ilOpn-cFlQ-B9wQuA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rLv8okEg78ilOpn-cFlQ-B9wQuA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Recently I had been contacted by a representative from &lt;a href="http://www.manning.com"&gt;Manning Publishing&lt;/a&gt; to do a book review about an upcoming book about &lt;a href="http://www.manning.com/williams/"&gt;C++ Concurrency in Action&lt;/a&gt; by Anthony Williams. I&amp;#8217;ve been lucky enough to get access to preview of the book while it&amp;#8217;s being written&amp;#8212;and now I&amp;#8217;m posting a public review of my thoughts on the book.&lt;/p&gt;&lt;p&gt;I for example have in the past written a lot about &lt;a href="http://blog.cplusplus-soup.com/search/label/parallel"&gt;parallel programming&lt;/a&gt; ranging from &lt;a href="http://blog.cplusplus-soup.com/2008/11/sea-change-in-parallel-programming.html"&gt;observations in the changes to come in parallel computing&lt;/a&gt; and &lt;a href="http://blog.cplusplus-soup.com/2008/10/parallel-computing-on-desktop.html"&gt;parallel computing on the desktop&lt;/a&gt; to &lt;a href="http://blog.cplusplus-soup.com/2008/11/io-bound-application-redux-with-code.html"&gt;code samples on parallel programming&lt;/a&gt; . I was fortunate enough to get a preview of the book and in this post I note down my take on it.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.justsoftwaresolutions.co.uk/"&gt;Anthony Williams&lt;/a&gt; (maintainer of &lt;a href="http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html"&gt;Boost.Thread&lt;/a&gt;) has been one of the main proponents of the push to include a threading library as part of the C++ Standard Template Library. In his &lt;a href="http://www.manning.com/williams"&gt;upcoming book&lt;/a&gt; he writes very eloquently and in a very readable manner about the good, bad, ugly, and beautiful aspects of writing concurrent programs. He uses a conversational style of writing to make his point which is a delight to read especially since the subject matter is fairly complex.&lt;/p&gt;&lt;p&gt;His book is chock full of insights from various levels in designing and implementing concurrent C++ applications using the upcoming C++ standard threading library. He also points out implementations already available in Boost.Thread as well as idioms and techniques into writing effective solutions to common issues faced with concurrency and C++.&lt;/p&gt;&lt;p&gt;He also writes very well about common pitfalls in adapting certain data structures and algorithms from a purely sequential and single-threaded view to thead-safe equivalents. For instance he writes about the problems you&amp;#8217;ll encounter when locking mutexes and certain design decisions that have to be made when implementing concurrency-aware abstract data types.&lt;/p&gt;&lt;p&gt;Interestingly he takes the reader through a well thought out series of evolutions of solutions and approaches written in succinct and very representative &amp;#8220;real world&amp;#8221; C++ code. He uses this style when introducing new concepts as well as going back into earlier slightly discussed and deferred topics. This is welcome especially for those who have been doing concurrent programming for a long time already and should work equally well for those who have not yet been exposed to much of the intricacies of concurrency-aware programming in C++.&lt;/p&gt;&lt;p&gt;When the book does come out, expect to see a thorough discourse and handy manuscript on the evolution of C++ into the concurrent application development space, new tools for every C++ programmer&amp;#8217;s toolbox, great tips and insights, and overall great advice when approaching concurrent application development in C++. It is very well written and definitely worth every penny you invest in it especially if you intend to future-proof yourself from the challenges of multi-core programming with C++.&lt;/p&gt;&lt;p&gt;Overall it&amp;#8217;s a must-read if you intend to ride the wave of developing concurrent applications that take advantage of the new multi-core processor architectures. It&amp;#8217;s a book you shouldn&amp;#8217;t pass up if you intend on being productive with C++ for a long time to come.&lt;/p&gt;&lt;p&gt;I will definitely look forward to this book when it does go out for distribution. Do not miss this opportunity to learn from one of the recognized experts in C++ as far as concurrency programming is concerned. You can &lt;a href="http://www.manning.com/williams/"&gt;pre-order your copy&lt;/a&gt; today.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12142884-6872038334566010291?l=blog.cplusplus-soup.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Rkx2MgOS"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=cC7qTyM4"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=42" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=nVuk91vS"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=5iVXLhFQ"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=C1yJRu3K"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=C1yJRu3K" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=Bkvy0u3x"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=Bkvy0u3x" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=hckLoaTo"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=45" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=wnaZXqVh"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=wnaZXqVh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=SbrGxqXm"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=bEOgT1S6"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=bEOgT1S6" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=e45WQiCE"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=JaO3kDze"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?i=JaO3kDze" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=ZGo3pg86"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=8j0waRR6"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=124" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/CppSoup?a=osNYuQCf"&gt;&lt;img src="http://feeds.feedburner.com/~f/CppSoup?d=131" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CppSoup/~4/IlbBkr_uj6I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.cplusplus-soup.com/feeds/6872038334566010291/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=12142884&amp;postID=6872038334566010291" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6872038334566010291" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/12142884/posts/default/6872038334566010291" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CppSoup/~3/IlbBkr_uj6I/c-concurrency-in-action-preview.html" title="C++ Concurrency in Action - A (P)Review" /><author><name>Dean Michael</name><uri>http://www.blogger.com/profile/12475688728121462783</uri><email>mikhailberis@gmail.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="15004271460694900294" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.cplusplus-soup.com/2008/11/c-concurrency-in-action-preview.html</feedburner:origLink></entry></feed>
