<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stefan-Marr.de &#187; Smalltalk</title>
	<atom:link href="http://soft.vub.ac.be/~smarr/tag/smalltalk/feed/" rel="self" type="application/rss+xml" />
	<link>http://soft.vub.ac.be/~smarr</link>
	<description>personal and research notes</description>
	<lastBuildDate>Tue, 24 Jan 2012 18:41:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>CSOM/PL: A Virtual Machine Product Line</title>
		<link>http://soft.vub.ac.be/~smarr/2011/12/csompl-a-virtual-machine-product-line/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=csompl-a-virtual-machine-product-line</link>
		<comments>http://soft.vub.ac.be/~smarr/2011/12/csompl-a-virtual-machine-product-line/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 21:09:46 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[ADL]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[CSOM]]></category>
		<category><![CDATA[FOP]]></category>
		<category><![CDATA[MDSoC]]></category>
		<category><![CDATA[Product lines]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VM]]></category>
		<category><![CDATA[VMADL]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=512</guid>
		<description><![CDATA[Welcome to Academia. That is how I take this one&#8230; Publishing can really be an odyssey, and it all started with my Master thesis. Today, we have the 28th of December 2011. And I think I handed my thesis in somewhere around the 23rd of September 2008. I agree that there have been issues with [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to Academia. That is how I take this one&#8230;</p>
<p>Publishing can really be an odyssey, and it all started with my Master thesis. Today, we have the 28th of December 2011. And I think I handed my thesis in somewhere around the 23rd of September 2008. I agree that there have been issues with the original version of the paper, but nothing was so fundamental that it would explain the more than three years it took to get it finally out. <img src='http://soft.vub.ac.be/~smarr/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Thank for the warm welcome anyway.</p>
<p><strong>Abstract</strong></p>
<blockquote>
<p>CSOM/PL is a software product line SPL derived from applying multi-dimensional separation of concerns MDSOC techniques to the domain of high-level language virtual machine VM implementations. For CSOM/PL, we modularised CSOM, a Smalltalk VM implemented in C, using VMADL virtual machine architecture description language. Several features of the original CSOM were encapsulated in VMADL modules and composed in various combinations. In an evaluation of our approach, we show that applying MDSOC and SPL principles to a domain as complex as that of VMs is not only feasible but beneficial, as it improves understandability, maintainability, and configurability of VM implementations without harming performance.</p></blockquote>
<ul>
	<li>CSOM/PL: A Virtual Machine Product Line, <em>Michael Haupt</em>, <em>Stefan Marr</em>, <em>Robert Hirschfeld</em>, Journal of Object Technology, Volume 10, (2011), pp. 12:1-30.</li>
	<li>Paper: <a title="CSOM/PL: A Virtual Machine Product Line" href="http://soft.vub.ac.be/~smarr/downloads/jot11-mhaupt-csompl-a-virtual-machine-product-line.pdf">PDF</a>.</li>
	<li>BibTex: <a href="http://www.bibsonomy.org/bibtex/2410111b6472d242e566afe4d27c3b7de/gron">BibSonomy</a></li>
        <li>DOI: <a href="http://dx.doi.org/10.5381/jot.2011.10.1.a12">doi:10.5381/jot.2011.10.1.a12</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2011/12/csompl-a-virtual-machine-product-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using R to Understand Benchmarking Results</title>
		<link>http://soft.vub.ac.be/~smarr/2011/09/using-r-to-understand-benchmarking-results/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-r-to-understand-benchmarking-results</link>
		<comments>http://soft.vub.ac.be/~smarr/2011/09/using-r-to-understand-benchmarking-results/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 11:15:18 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[RoarVM]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[Statistics]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=441</guid>
		<description><![CDATA[Why R? Evaluating benchmark results with Excel became too cumbersome and error prone for me so that I needed an alternative. Especially, reevaluating new data for the same experiments was a hassle. However, the biggest problem with Excel was that I did not know a good way to query the raw data sets and group [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript" src="http://soft.vub.ac.be/~smarr/renaissance/code/shCore.js"></script>
<script type="text/javascript" src="http://soft.vub.ac.be/~smarr/renaissance/code/shBrushR.js"></script>
<link type="text/css" rel="stylesheet" href="http://soft.vub.ac.be/~smarr/renaissance/code/shCoreDefault.css"/>

<h2>Why R?</h2>

<p>Evaluating benchmark results with Excel became
   too cumbersome and error prone for me so that I needed an alternative.
   Especially, reevaluating new data for the same experiments was a hassle.
   However, the biggest problem with Excel was that I did not know a good
   way to query the raw data sets and group results easily to
   be able to answer different kind of questions about the data.
   Thus, I decided I need to learn how to do it in a better way.
   Since, I was not really happy with the debuggability, traceability,
   and reusability of my spreadsheets either, I gave up on Excel entirely.
   I bet, Excel can do most of the things I need, but I wanted a text-based
   solution for which I can use my normal tools, too.</p>

<p>While working on <a href="https://github.com/smarr/ReBench">ReBench</a>,
   I got already in touch with
   <a href="http://matplotlib.sourceforge.net/">matplotlib</a> to generate
   simple graphs from benchmark results automatically.
   But well, Python does not feel like the ultimate language for what I was
   looking for either. Instead, <a href="http://www.r-project.org/">R</a> was
   mentioned from time to time when it came to statistical evaluation of
   measurements. And, at least for me, it turned out to be an interesting
   language with an enormous amount of libraries. Actually, a bit
   to enormous for my little needs, but it looked like a good starting
   point to brush up on my statistics knowledge.</p>

<p>By now, I use it regularly and applied it to a number of problems,
   including my work on the <a href="https://github.com/smarr/RoarVM">RoarVM</a>
   and a paper about
   <a href="http://www.hpi.uni-potsdam.de/hirschfeld/projects/som/index.html#csompl">CSOM/PL</a>.</p>
   
<h2>Benchmark Execution</h2>

<p>Before we can analyze any benchmark results, we need a reliable way to
   execute them, ideally, as reproducible as possible. For that purpose,
   I use a couple of tools:</p>
   <dl>
     <dt><a href="https://github.com/smarr/ReBench">ReBench</a></dt>
     <dd>A Python application that executes benchmarks based on a given
         configuration file that defines the variables to be varied,
         the executables to be used and the benchmarks and their
         parameters.</dd>
     <dt><a href="http://www.squeaksource.com/SMark.html">SMark</a></dt>
     <dd>A Smalltalk benchmarking framework that allows one to write
         benchmarks in a style similar to how unit-tests are written.</dd>
     <dt><a href="https://github.com/tobami/codespeed">Codespeed</a></dt>
     <dd>This is mostly for the bigger picture, a web application
         that provides the basic functionality to track long-term
         performance of an application.<br/><br/></dd>
  </dl>

<p>Beside having good tools, serious benchmarking requires some background
   knowledge. Today&#8217;s computer systems are just to complex to get good
   results with the most naive approaches.
   In that regard, I highly suggest to read the following two
   papers which discussing many of the pitfalls that one encounters when
   working with modern virtual machines, but also just on any modern
   operating system and with state-of-the-art processor tricks.</p>
   
   <ul>
     <li><em>Georges, A.; Buytaert, D. &#038; Eeckhout, L.</em><br/>
         <a href="http://dx.doi.org/10.1145/1297105.1297033">Statistically Rigorous Java Performance Evaluation</a><br/>
         SIGPLAN Not., ACM, 2007, 42, 57-76. (<a href="http://itkovian.net/base/files/papers/oopsla2007-georges-preprint.pdf">PDF</a>)</li>
     <li><em>Blackburn, S. M.; McKinley, K. S.; Garner, R.; Hoffmann, C.; Khan, A. M.; Bentzur, R.; Diwan, A.; Feinberg, D.; Frampton, D.; Guyer, S. Z.; Hirzel, M.; Hosking, A.; Jump, M.; Lee, H.; Moss, J. E. B.; Phansalkar, A.; Stefanovik, D.; VanDrunen, T.; von Dincklage, D. &#038; Wiedermann, B.</em></li>
         <a href="http://dx.doi.org/10.1145/1378704.1378723">Wake Up and Smell the Coffee: Evaluation Methodology for the 21st Century</a>
         Commun. ACM, ACM, 2008, 51, 83-89. (<a href="http://domino.watson.ibm.com/comm/research_people.nsf/pages/hirzel.index.html/$FILE/cacm08-dacapo-benchmarks.pdf">PDF</a>)</li>
   </ul>
   

<h2>Getting Started with R</h2>

<p>Now, we need to find the right tools to get started with R.
   After searching a bit, I quickly settled on
   <a href="http://www.rstudio.org/">RStudio</a>. It feels pretty much like
   a typical IDE with a <a href="http://en.wikipedia.org/wiki/Read-eval-print_loop">REPL</a>
   at its heart. As you can see in the screenshot
   below, there are four important areas. Top-left are your *.R files
   in a code editor with syntax highlighting and code completion. Top-right
   is your current R workspace with all defined variables and functions.
   This allows also to view and explore your current data set easily.
   On the bottom-right, we got a window that usually contains either
   help texts, or plots.
   Last but not least, in the bottom-left corner is the actual REPL.</p>

<p><a href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/RStudio.png"><img
class="aligncenter size-medium wp-image-444" title="Screenshot of RStudio"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/RStudio-300x187.png"
alt="Screenshot of RStudio" width="300" height="187" /></a></p>

<p><code>Rscript</code> is the interpreter that can be used on the command-line
   and thus, is nice to have for automating tasks. I installed it using MacPorts.</p>

<p>This introduction is accompanied by a
   <a href="https://github.com/smarr/BenchR/blob/master/using-R-to-understand-benchmarking-results.R">script</a>.
   It contains all the code discussed here and can be used to follow the
   introduction avoiding to much copy&#8217;n'past. Furthermore, the code here
   is not as complete as the script, to be a little more concise.</p>

<p>The first thing to do after setting up R is to install some libraries.
   This can be done easily from the REPL by executing the following code:
   <code>install.packages("plyr")</code>. This will
   install the <code>plyr</code> library providing <code>ddply()</code>,
   which we are going to use later to process our data set.
   Before it is going to install the code, it will ask for a mirror nearby
   to download the necessary files.
   To visualize the benchmark results afterwards, we are going to use bean plots
   from the <code>beanplot</code> library. The <code>doBy</code> library
   provides some convenience functions from which we are going to use
   <code>orderBy()</code>.
   After the installing all libraries, they can be loaded by executing
   <code>library(lib_name)</code>.</p>

<p>The documentation for functions, libraries, and other topics is always
   just a question mark away. For instance, to find out how libraries are installed,
   execute the following code in the REPL: <code>?install.packages</code>.

<h2>Preprocessing Benchmark Results</h2>

<p>To give a little context, the experiment this introduction is based on
   tries to evaluate the impact of using an object table instead of direct
   references on the performance of our manycore Smalltalk, the RoarVM.</p>

<p>The data set is available here:
   <a href="http://stefan-marr.de/downloads/object-table-data.csv.bz2">object-table-data.csv.bz2</a>.
   Download it together with the <a href="https://raw.github.com/smarr/BenchR/master/using-R-to-understand-benchmarking-results.R">script</a> and
   put it into the same folder.
   After opening the script in RStudio, you can follow the description here
   while using the code in RStudio directly. The run-button will execute a
   line or selection directly in the REPL.</p>

<h3>Loading Data</h3>

<p>First, change the working directory of R to the directory where you put
   the data file: <code>setwd("folder/with/data-file.csv.bz2/")</code>.
   The file is a compressed comma-separated values file that contains
   benchmark results, but no header line. Furthermore, some of the rows do not
   contain data for all columns, but this is not relevant here and we can just
   fill the gabs automatically.
   Load the compressed data directly into R&#8217;s workspace by
   evaluating the following code:</p>
   
<pre class="brush: r; toolbar: false;">
bench &lt;- read.table("object-table-data.csv.bz2",
                    sep="\t", header=FALSE,
                    col.names=c("Time", "Benchmark", "VirtualMachine",
                                "Platform", "ExtraArguments", "Cores",
                                "Iterations", "None", "Criterion",
                                "Criterion-total"),
                    fill=TRUE)
</pre>

<p>As you can see in the workspace on the right, the variable <code>bench</code>
   contains now 60432 observations for 10 variables. Type the following
   into the REPL to get an idea of what kind of data we are looking at:
   <code>summary(bench)</code>, or <code>View(bench)</code>.
   Just typing <code>bench</code> into the REPL will print the plain content,
   too.
   As you will see, every row represents one measurement with a set of
   properties, like the executed benchmark, its parameters, and the virtual 
   machine used.
</p>

<h3>Transforming Raw Data</h3>

<p> As a first step, we will do some parsing and rearrange the data to
    be able to work with it more easily. The name of the virtual machine binary
    encodes a number of properties that we want to be able to access directly.
    Thus, we split up that information into separate columns. </p>

<pre class="brush: r; toolbar: false;">
bench &lt;- ddply(bench,
               ~ VirtualMachine, # this formula groups the data by the value in VirtualMachine
               transform,
               # the second part of the VM name indicates whether it uses the object table
               ObjectTable = strsplit(as.character(VirtualMachine), "-")[[1]][2] == "OT",
               # the third part indicates the format of the object header
               Header = factor(strsplit(as.character(VirtualMachine), "-")[[1]][3]))  
</pre>

<p> This operation could use some more explanation, but most important
    know now is that we add the two new columns and that the data
    is being processed grouped by the values in the <code>VirtualMachine</code>
    column. </p>

<p> The data set contains also results from another experiment and some of the
    benchmarks include very detailed information. Neither of those information
    is required at the moment and we can drop the irrelevant data points
    by using <code>subset</code>. </p>

<pre class="brush: r; toolbar: false;">
bench &lt;- subset(bench,
                Header == "full"         # concentrate on the VM with full object headers
                 &#038; Criterion == "total", # use only total values of a measurement
                select=c(Time, Platform, # use only a limited number of columns
                         ObjectTable, Benchmark, ExtraArguments, Cores))
</pre>

<p> Furthermore, we assume that all variations in measurements come from the
    same non-deterministic influences. This allows to order the measurements,
    before correlating them pair-wise. The data is order based on all columns,
    where <code>Time</code> is used as the first ordering criterion. </p>

<pre class="brush: r; toolbar: false;">
bench &lt;- orderBy(~Time + Platform + ObjectTable + Benchmark + ExtraArguments + Cores, bench)
</pre>

<h3>Normalizing Data</h3>

<p> In the next step, we can calculate the speed ratio between pairs of
    measurements. To that end, we group the data based the unrelated variables
    and divide the measured runtime by the corresponding measurement of the VM
    that uses an object table. Afterwards we drop the measurements for the VM
    with an object table, since the speed ratio here is obviously always 1.
</p>

<pre class="brush: r; toolbar: false;">
norm_bench &lt;- ddply(bench, ~ Platform + Benchmark + ExtraArguments + Cores,
                    transform,
                    SpeedRatio = Time / Time[ObjectTable == TRUE])
norm_bench &lt;- subset(norm_bench, ObjectTable == FALSE, c(SpeedRatio, Platform, Benchmark, ExtraArguments, Cores))
</pre>

<h2>Analyzing the Data</h2>

<h3>The Basics</h3>

<p> Now we are at a point were we can start to make sense of the benchmark
    results.
    The summary function provides now a useful overview of the data and
    we can for instance concentrate on the speed ratio alone.
    As you might expect, you can also get properties like the standard
    deviation, arithmetic mean, and the median easily: </p>

<pre class="brush: r; toolbar: false;">
summary(norm_bench$SpeedRatio)
sd(norm_bench$SpeedRatio)
mean(norm_bench$SpeedRatio)
median(norm_bench$SpeedRatio)
</pre>

<p> However, that is very simple, a bit more interesting are R&#8217;s features
    to query and process the data. The first question we are interested
    in is, whether there is actually an impact on the performance difference
    for different numbers of cores: </p>

<pre class="brush: r; toolbar: false;">
summary(norm_bench$SpeedRatio[norm_bench$Cores==1])
summary(norm_bench$SpeedRatio[norm_bench$Cores==16])
</pre>

<h3>Beanplots</h3>

<p> Starring at numbers is sometimes informative, but usually only useful
    for small data sets.
    Since we humans are better in recognizing patterns in visual representations,
    <a href="http://www.jstatsoft.org/v28/c01/paper">beanplots</a> are a better
    way to make sense of the data. They are an
    elegant visualization of the distribution of measurements. </p>

<pre class="brush: r; toolbar: false;">
beanplot(SpeedRatio ~ Platform,
         data = norm_bench,
         what = c(1,1,1,0), log="",
         ylab="Runtime: noOT/OT",
         las=2)
</pre>

<p><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/overall-distribution-beanplot.png"><img
class="aligncenter size-medium wp-image-454" title="Beanplot of the overall
distribution of all measurements"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/overall-distribution-beanplot-300x180.png"
alt="" width="300" height="180" /></a></p>


<p> This beanplot tells us, like the numbers before, that the mean is smaller
    than 1, which is the expected result and means that the indirection
    of an object table slows the VM down. However, the numbers did not tell
    use that there are various clusters of measurements that now become visible
    in the beanplot and are worth investigating. </p>

<p> Let&#8217;s look at the results split up by number of cores. </p>

<pre class="brush: r; toolbar: false;">
beanplot(SpeedRatio ~ Cores,
         data = norm_bench,
         what = c(1,1,1,0), log="",
         ylab="Runtime: noOT/OT")
</pre>

<p><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-cores.png"><img
class="aligncenter size-medium wp-image-455" title="Distribution of
measurements split up by cores"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-cores-300x180.png"
alt="" width="300" height="180" /></a></p>

<h3>Digging Deeper</h3>

<p> While noticing that the variant without object table is faster
    for more cores, we also see that the speed ratios are distributed unevenly.
    While the bean for 1-core has a 2-parted shape, the 2-cores bean has a lot
    more points where measurements clump.
    That is probably related to the benchmarks: </p>

<pre class="brush: r; toolbar: false;">
beanplot(SpeedRatio ~ Benchmark,
         data = subset(norm_bench, Cores==2),
         what = c(1,1,1,0), log="",
         ylab="Runtime: noOT/OT", las=2)
beanplot(SpeedRatio ~ Benchmark,
         data = subset(norm_bench, Cores==16),
         what = c(1,1,1,0), log="",
         ylab="Runtime: noOT/OT", las=2)
</pre>

<p class="aligncenter"><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-benchmarks-cores2.png"><img
class="size-thumbnail wp-image-457" title="Results for 2 cores"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-benchmarks-cores2-150x150.png"
alt="" width="150" height="150" /></a>

<a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-benchmarks-cores16.png"><img
class="size-thumbnail wp-image-458" title="Results for 16 cores"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/distribution-by-benchmarks-cores16-150x150.png"
alt="" width="150" height="150" /></a></p>

<p> Those two graphs are somehow similar, but you might notice that the float
    loop benchmark has a couple of strong outliers.
    I forgot the exact identifier of the float loop benchmark, so lets find out
    with this code: <code>levels(norm_bench$Benchmark)</code><br/>
    Now let&#8217;s filer the data shown by that benchmark. </p>

<pre class="brush: r; toolbar: false;">
beanplot(SpeedRatio ~ Cores,
         data = subset(norm_bench, Benchmark == "SMarkLoops.benchFloatLoop"),
         what = c(1,1,1,0), log="", ylab="Runtime: noOT/OT")
</pre>

<p><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/float-bench-per-core.png"><img
class="aligncenter size-medium wp-image-463" title="Results for the float loop
benchmark split up by cores"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/float-bench-per-core-300x180.png"
alt="" width="300" height="180" /></a></p>


<p> This visualization reassures me, that there is something strange going on.
    The distribution of result still looks clumped as if there is another
    parameter influencing the result, which we have not regarded yet.
    The only column we have not looked at is <code>ExtraArguments</code>,
    so we will add them. Note that <code>droplevels()</code> is applied on the
    data set this time before giving it to the <code>beanplot()</code> function.
    This is necessary since the plot would contain all unused factor levels
    instead, which would reduce readability considerably. </p>

<pre class="brush: r; toolbar: false;">
beanplot(SpeedRatio ~ Cores + ExtraArguments,
         data = droplevels(subset(norm_bench, Benchmark == "SMarkLoops.benchFloatLoop")),
         what = c(1,1,1,0), log="", ylab="Runtime: noOT/OT", las=2)
</pre>

<p><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/float-bench-per-core-and-extra-arguments.png"><img
class="aligncenter size-medium wp-image-464" title="Results of the float loop
benchmark split up by cores and extra benchmark arguments"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/float-bench-per-core-and-extra-arguments-300x180.png"
alt="" width="300" height="180" /></a></p>


<h3>Fixing up a Mistake</h3>

<p> This plot now shows us that there are three groups of results with
    different <code>ExtraArguments</code>.
    Think I forgot that the data set contains some very specific benchmarks.
    The overall goal of the benchmarks is to test the weak scaling behavior of
    the VM by increasing work-load and number-of-cores together.
    However, for the questions we are interested here, only those weak-scaling
    benchmarks are of interest.
    Thus, we need to filter out a couple of more data points, since the results
    will be unnecessarily biased otherwise.
    To filter the data points we use <code>grepl</code>.
    It matches the strings of <code>ExtraArguments</code> and allows us to
    filter out the single-core and the 10x-load benchmarks.</p>

<pre class="brush: r; toolbar: false;">
norm_bench &lt;- subset(norm_bench,
                     !grepl("^1 ", ExtraArguments)    # those beginning with "1" put load on a single core
                     &#038; !grepl("s0 ", ExtraArguments)) # those having "s0" in it put 10x load on each core
norm_bench &lt;- droplevels(norm_bench)
</pre>

<p> And since I always wanted to say that: 
    The exercise to regenerate all interesting graphs and re-answer the
    original questions are left to the interested reader. <img src='http://soft.vub.ac.be/~smarr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> 

<h2>Conclusion</h2>

<p> As a final graph, we can plot all benchmarks for all cores,
    and get an overview. The <code>par</code> function allows to adapt the
    margins of the plot, which is necessary here to get the full benchmark
    names on the plot. </p>

<pre class="brush: r; toolbar: false;">
par(mar=c(20, 4, 1, 1))
beanplot(SpeedRatio ~ Cores + Benchmark,
         data = norm_bench,
         what = c(1,1,1,0), log="",  ylab="Runtime: noOT/OT", las=2)
</pre>

<p><a
href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/final-overview.png"><img
class="aligncenter size-medium wp-image-465" title="Overview split by number
of cores and benchmarks"
src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/09/final-overview-300x180.png"
alt="" width="300" height="180" /></a></p>

<p> As we already knew, we see an influence of the number of cores on the
 results, but more importantly, we see most benchmarks benefitting from removing
 the extra indirection through the object table. The float loops benefit by
 far the strongest. The float objects are so small and usually used only
 temporary that avoiding the object table pays off.
 For the integer loops it does not make a difference, since the VMs uses
 immediate values (tagged integers). Thus, the integers used here are not
 objects allocated in the heap and the object table is not used either. </p>

<p> Beyond the won insight into the performance implications of an object table
    this analysis also demonstrates the benefits of using a language like
    R. Its language features allow us to filter and reshape data easily.
    Furthermore, regenerating plots and tracing steps becomes easy, too.
    Here it was necessary since some data points needed to be removed from
    the data set to get to reasonable results. Reexecuting part of the script
    or just exploring the data is convenient and done
    fast, which allows me to ask more questions about the data and understand the
    measurements more deeply. Furthermore, it is less a hassle to reassess
    the data in case certain assumptions have changed, we made a mistake,
    or the data set changed for other reasons.
    From my experience, it is much more convenient than Excel, but that might
    just be because I spend more time on learning R than on learning Excel. </p>

<p> In case you try it out yourself, you will certainly want to experiment
    with other types of visualizations, save them to files, etc.
    A few of these things can be found in my benchmarking scripts on
    GitHub: <a href="https://github.com/smarr/BenchR">BenchR</a>.</p>

<script type="text/javascript">SyntaxHighlighter.all();</script>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2011/09/using-r-to-understand-benchmarking-results/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sly and the RoarVM: Exploring the Manycore Future of Programming</title>
		<link>http://soft.vub.ac.be/~smarr/2011/08/sly-and-the-roarvm-exploring-the-manycore-future-of-programming/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sly-and-the-roarvm-exploring-the-manycore-future-of-programming</link>
		<comments>http://soft.vub.ac.be/~smarr/2011/08/sly-and-the-roarvm-exploring-the-manycore-future-of-programming/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 14:01:34 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Renaissance]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[behavior]]></category>
		<category><![CDATA[emergence]]></category>
		<category><![CDATA[garbage collection]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Manycore]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[Nondeterministic]]></category>
		<category><![CDATA[pauseless]]></category>
		<category><![CDATA[Sly]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[TILE64]]></category>
		<category><![CDATA[Tilera]]></category>
		<category><![CDATA[Virtual Machines]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=416</guid>
		<description><![CDATA[Today, I gave a talk at the ExaScience Lab, Intel Labs Europe in Leuven at IMEC. I talked mainly about the idea of nondeterministic programming, the Sly programming language and some details on our Smalltalk manycore virtual machine that enables those experiments. Thus, tried to spread the word about our Renaissance project at bit further. [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I gave a talk at the <a href="http://www.exascience.com/">ExaScience Lab, Intel Labs Europe</a> in Leuven at IMEC. I talked mainly about the idea of nondeterministic programming, the Sly programming language and some details on our Smalltalk manycore virtual machine that enables those experiments. Thus, tried to spread the word about our <a href="http://soft.vub.ac.be/~smarr/renaissance/">Renaissance project</a> at bit further.</p>
<p>Below you can find the abstract and slides.</p>
<p><strong>Abstract</strong></p>
<blockquote>
<p>The manycore future has several challenges ahead of us that suggest that fundamental assumptions of contemporary programming approaches do not apply anymore when scalability is required.</p>
<p>Sly is a language prototype designed to experiment with the inherently nondeterministic properties of parallel systems. It is designed to enable programmers to embrace nondeterminism instead of guiding them to fight it. Nature shows that complex system can be built from independent entities that achieve a common goal without global synchronization/communication. Sly is design to enable the prototyping of algorithms that show such emerging behavior. It will be introduced in the first part of the talk.</p>
<p>The second part of the talk will focus on the underlying problems of building virtual machines for the manycore future, which allow to harness the available computing power. The RoarVM was design to experiment on the Tilera TILE64 manycore processor architecture which provides 64 cores and characteristics that are distinctly different from today&#8217;s commodity multicore processors. Memory bandwidth, caches and communication are the biggest challenges on such architectures and this talk will give a brief overview over the design choices of the RoarVM which tackle the characteristics of the TILE64 architecture.</p>
<p>&nbsp;</p>

<p>Acknowledgement: Sly and the RoarVM were designed and implemented by David Ungar and Sam Adams at IBM Research.</p></blockquote>
<div style="width:425px" id="__ss_8991354"> <iframe src="http://www.slideshare.net/slideshow/embed_code/8991354" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe> </div>]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2011/08/sly-and-the-roarvm-exploring-the-manycore-future-of-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Sly3 Programming Language</title>
		<link>http://soft.vub.ac.be/~smarr/2011/08/the-sly3-programming-language/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-sly3-programming-language</link>
		<comments>http://soft.vub.ac.be/~smarr/2011/08/the-sly3-programming-language/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 07:19:02 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Renaissance]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[course work]]></category>
		<category><![CDATA[emergence]]></category>
		<category><![CDATA[Ly]]></category>
		<category><![CDATA[Manycore]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[Nondeterministic]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[RoarVM]]></category>
		<category><![CDATA[Sly]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[Squeak]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=405</guid>
		<description><![CDATA[The following introduction and analysis of the Sly3 programming language was written by Pablo Inostroza Valdera as part of his course work for the Multicore Programming course of Tom Van Cutsem. The assignment was to write a blog post about a topic of their own choice, and I repost Pablo&#8217;s work here with his permission [...]]]></description>
			<content:encoded><![CDATA[  <script type="text/javascript" src="http://soft.vub.ac.be/~smarr/renaissance/code/shCore.js"></script>
  <script type="text/javascript" src="http://soft.vub.ac.be/~smarr/renaissance/code/shBrushSmalltalk.js"></script>
  <link type="text/css" rel="stylesheet" href="http://soft.vub.ac.be/~smarr/renaissance/code/shCoreDefault.css"/>

<p>The following introduction and analysis of the Sly3 programming language was written by Pablo Inostroza Valdera as part of his course work for the <a href="http://soft.vub.ac.be/~tvcutsem/multicore/">Multicore Programming course</a> of Tom Van Cutsem. The assignment was to write a blog post about a topic of their own choice, and I repost Pablo&#8217;s work here with his permission to spread the word about Sly a bit wider. We made his article also available as part of his work for the <a href="http://soft.vub.ac.be/~smarr/renaissance/">Renaissance project</a> itself.</p>

 <h2 style="text-align:center;margin-top:80px;"><a href="http://soft.vub.ac.be/~tvcutsem/multicore/index.html">Multicore Programming, Course Work</a></h2>
  <h1 style="text-align:center;">The <span class="sly">Sly3</span> Programming Language</h1>

  <h3 style="text-align:center;">Pablo Inostroza Valdera</h3>
  <h3 style="text-align:center;"><code>&lt; pinostro _ vub.ac.be &gt;</a></code></h3>

  <h3 style="text-align:center;">23 June 2011</h3>

  <h1>Introduction</h1>

  <p><span class="sly">Sly3</span> is a Smalltalk dialect that features two
  concepts in order to deal with parallelism: <em>ensembles</em>, which are
  collections of objects that can receive parallel messages, and modifiers,
  which decorate messages in order to modify their parallel behavior
  (<em>adverbs</em>) or to specify how to handle reductions
  (<em>gerunds</em>). In this article we analyze <span
  class="sly">Sly3</span>&#8216;s programming model.</p>

  <p><span class="sly">Sly3</span> is a language being developed in the
  context of the <a
  href="http://soft.vub.ac.be/~smarr/renaissance/">Renaissance Project</a>, at
  IBM. With <span class="sly">Sly3</span>, their authors David Ungar and Sam
  Adams explore abstractions for nondeterministic parallel programming. <span
  class="sly">Sly3</span> is the experimental successor of L<small>Y</small>,
  a javascript-like interpreted language that was implemented on top of
  Smalltalk[<a href= "#Ungar2010">UA10</a>]. As the 3 in Sly3 indicates, Sly
  itself underwent already three iterations of design. The main idea behind
  the design of <span class="sly">Sly3</span> is that multicore programming is
  commonly addressed by restricting the nondeterminism parts and trying to
  enforce strict determinism. As an example of this, Ungar and Adams refer to
  the actors paradigm. While the actor model certainly adds some order to
  concurrent computations, the truth is that some nondeterminism still
  persists because the global order in which messages arrive to an actor is
  nondeterministic. They proposed that instead of trying to restrict the
  nondeterminism, it should be embraced. The <span class="sly">Ly</span>
  language and, later on, the <span class="sly">Sly3</span> language are steps
  towards that direction. In this article we discuss the latter.</p>

  <h1>Ensembles, or How to Represent A Flock of Birds</h1>

  <p><span class="sly">Sly3</span>&#8216;s key elements were conceived by observing the
  nature. Think of a flock of birds, an ant colony or a school of fishes.
  These are all examples for a multitude of independent agents, acting in a
  nondeterministic way, whose aggregated behavior is more complex than that
  of the individuals. In other words, a more complex behavior <span class=
  "textit">emerges</span>. The idea of a whole formed from independent units
  is key to <span class="sly">Sly3</span>, and it has been reflected in the concept of
  an <em>ensemble</em>. An ensemble is a collection of
  objects, subject of receiving messages as a whole. In the following
  example, we create an ensemble and execute an operation on it:</p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false; gutter: false;">
  numbers := Sly3Ensemble with: {1. 2. 3. 4. 5}.
  squaredNumbers := numbers squared.
  </pre>
  </div>
  

  <p>This code yields: <code>%{1. 4. 9. 16. 25}</code>. Recall that the curly
  braces represent an array in Smalltalk. In Sly3, curly braces preceded by %
  denote an ensemble.</p>

  <p>Notice how the ensemble received a message as a whole, but it acted on
  each individual in order to produce a new ensemble with all of the elements
  squared. It is not surprising to know that the default behavior of this
  <em>mapping</em> is parallel, i.e., a different thread of execution is
  triggered for each individual computation. The standard execution strategy
  in this this simple example is as follows:</p>

  <ul>
    <li>The message was delegated to members of the ensemble, creating a
    parallel process for the evaluation of each of the messages. We can say
    that each member was treated <strong>individually</strong> and
    was executing its own <em>task</em>.</li>

    <li>For generating the final result, a new ensemble was created from the
    results of all the tasks of the previous step. We can say that we are
    <strong>ensembling</strong> together all the individual
    results.</li>
  </ul>

  <p>Notice that we have put in bold letters two words: individually and
  ensembling. We have done so, because both words characterize a strategy for
  handling a parallel computation. Actually, this is the default strategy in
  <span class="sly">Sly3</span>, but the programming model was designed to be able to
  customize these behaviors.</p>

  <h1>Adverbs and Gerunds, or How to Modulate Parallel Behavior</h1>
  
  <p>The basic model of message handling for an ensemble is:</p>

  <ol>
    
    <li>The ensemble that receives the message is treated in accordance to
        its <em>adverb</em>. A receiver&#8217;s adverb precedes the
        message name. In the absence of an explicit one, the default adverb for
        receiver, namely <code>individualLY</code>, is used.
        We elaborate on the meaning of <code>individualLY</code> in subsequent
        paragraphs, important here is to note that adverbs&#8217; names always end in <em>LY</em>.
    </li>

    <li>If there are operands, they have to be treated in accordance with
    their <em>adverbs</em>. An operand adverb follows the
    message name. In the absence of an explicit one, the default adverb for
    operands, namely <code>wholLY</code>, is used.</li>

    <li>The operation is executed according to an overall strategy, also
    determined by an <em>adverb</em>.</li>

    <li>The result of the operation is reduced in accordance to a
    <em>gerund</em>. In the absence of an explicit one,
    the default gerund, namely <code>ensemblING</code>, is used. Gerunds&#8217; names
    always end in <em>ING</em>.</li>
  </ol>

  <p>Regarding the point 3, it suffices to mention that currently there are
  only three overall strategies, namely, <em>serially</em>, <em>plainly</em> and the
  default one, which we can call <em>parallelly</em>.
  Note that the metaphor of the adverb is taken to an extreme in
  <span class="sly">Sly3</span>. Many words that do not sound like adverbs are
  <em>adverbialized</em> in order to fit in the
  conceptual framework.
  <em>Serially</em> forces serial executions, so no processes/threads
  are spawned to compute the results. This can be useful either for semantic
  reasons or when the cost of parallel execution is to high, i.e., when we
  are below the sequential threshold. The adverb <em>plainly</em> can be used to turn off ensemble behavior, and
  therefore, to treat the ensemble as a collection (e.g., we could ask for
  the size of an ensemble by using plainly, and this would not imply sending
  a message to each of its members). For the sake of brevity, we are not
  going to discuss the overall strategies further, since they are not
  relevant for grasping the essence of the <span class="sly">Sly3</span> programming
  model.</p>

  <table style="margin-left:auto;margin-right:auto;width:70%;">
        <tr>
          <th style="width:30%;"><strong>Adverb</strong></th>
          <th><strong>Informal description</strong></th>
        </tr>

        <tr>
          <td><code>wholLY</code></td>
          <td>just pass me along as a whole ensemble</td>          
        </tr>

        <tr>
          <td><code>individualLY</code></td>
          <td>create a process/thread for each of my members</td>
        </tr>

        <tr>
          <td><code>collectionLY</code></td>
          <td>treat me as a collection instead of an ensemble</td>
        </tr>

        <tr>
          <td><code>duplicativeLY</code></td>
          <td>copy each of my members, to produce a new ensemble</td>
        </tr>

        <tr>
          <td><code>roundLY</code></td>
          <td>create a process for each combination of the receiver&#8217;s members and my members</td>
        </tr>

        <tr>
          <td><code>randomLY</code></td>
          <td>chose <code>n</code> of my members randomly, <code>n</code> is a parameter of this
          adverb</td>
        </tr>

        <tr>
          <td><code>valueLY</code></td>
          <td>take a block and apply it to each of my members</td>
        </tr>

        <caption>
          <strong>Table 1:</strong> Some of the principal <em>adverbs</em> in <span class="sly">Sly3</span>.
        </caption>
    </table>

  <p>The syntax of <span class="sly">Sly3</span> is cumbersome, so next we present some
  examples in order to provide a more clear idea of how to express things in
  this language. Let&#8217;s analyze them in the light of three of the steps
  presented before (1, 2 and 4; 3 is excluded since are not going to discuss
  the <em>overall strategy</em>). In order to guide our
  analysis, figure <a href="#fig:table">1</a> presents a table with brief
  descriptions of some of the main adverbs in <span class="sly">Sly3</span>, and their
  impact on the message evaluation process. We have not included a similar
  table for gerunds, because their names are in general more self
  descriptive.</p>

  <p><strong>Example 1</strong></p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false; gutter: false;">
    %{true. true. false. true} andING
  </pre>
  </div>

  <ul>
    <li>In this example, there are no adverbs specified, therefore, the
    <em>receiver&#8217;s</em> adverb is the default one, i.e.,
    <em>individually</em>. This implies that the
    processing of the members is done independently (i.e. in different
    Smalltalk processes).</li>

    <li>There are no arguments, therefore, no argument&#8217;s adverb.</li>

    <li>There is a gerund <code>andING</code> that acts on the result of the
    operation reducing the independent results coming from different
    processes. As its name indicates, <code>andING</code> performs logical
    <em>and</em> over the members of the resulting
    ensemble. Notice that there no actual message specified here, thus,
    <code>andING</code> is applied to unchanged set of members of the
    ensemble.</li>

    <li>Therefore, the result of this operation is: <code>false</code>.</li>
  </ul>

  <p><strong>Example 2</strong></p>
  
  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false; gutter: false;">
    %{1. 2. 3} plusRoundLY: %{10. 20. 30}
  </pre></div>

  <ul>
    <li>Here are no adverbs specified for the receiver, therefore, the
    <em>receiver&#8217;s</em> adverb is the default one, i.e.,
    <em>individually</em>. This implies that the
    processing of the members is done independently (i.e. in different
    processes/threads).</li>

    <li><code>roundLY</code> is an argument to the operand (<code>%10. 20. 30</code>
    ). This adverb says: create a process/thread for each combination of the
    receiver&#8217;s member and the argument&#8217;s member; acting as a cartesian
    product.</li>

    <li>There is no gerund, which means that the default one
    (<code>ensemblING</code>) is used.</li>

    <li>Therefore, the result of this operation is: <code>%{11. 12. 13. 21. 22.
    23. 31. 32. 33}</code>.</li>
  </ul>

  <p><strong>Example 3</strong></p>
  
  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false; gutter: false;">
    %{1. 2. 3} valueLY: [ <img src='http://soft.vub.ac.be/~smarr/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' />  | x * 10]
  </pre></div>
  

  <ul>
    <li><code>valueLY</code> is an argument of the receiver, therefore, the
    receiver has to be mapped to a new ensemble using the given block as the
    <em>mapper</em>.</li>

    <li>There are no arguments, therefore, no argument&#8217;s adverb. Recall that
    the block is an argument to the adverb. As we can see, the problems of
    Sly3&#8242;s syntax become evident in these cases.</li>

    <li>Therefore, the result of this operation is: <code>%{10. 20.
    30}</code>.</li>
  </ul>

  <h1>An Overview of Sly3&#8242;s Implementation</h1>

  <p>In order to have a comprehensive view of the spectrum of the current
  <em>custom behaviors</em> available for direct use, in
  figure <a href="#fig:hierarchy">1</a> we show the hierarchy of gerunds and
  adverbs that we can find in the current image of <span class="sly">Sly3</span>.
  Notice that this forms a restricted vocabulary that we can use as a basis
  of more complex strategies, in a LEGO-like way. In fact, we can see this
  hierarchy as a custom domain-specific language suited for the description
  of common strategies for handling parallelism.</p>

<a href="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/08/sly-hierarchy.png"><img src="http://soft.vub.ac.be/~smarr/wp-content/uploads/2011/08/sly-hierarchy.png" alt="" title="The hierarchy of modifiers of Sly3." width="400" height="448" class="size-full wp-image-408" /></a>
<p style="text-align:center;"><strong>Figure 1:</strong> The hierarchy of modifiers of <span class="sly">Sly3</span>.</p>

  <p>Based on what we have discussed so far, we can characterize
  <span class="sly">Sly3</span> as:</p>

  <ul>
    <li>An Object-oriented language, descendant of Smalltalk, which
    incorporates ensembles as first-class entities to model parallelism.</li>

    <li>It features parallelism by default. As soon as a message is sent to
    an ensemble, it is assumed that the processing will be spawned as
    independent tasks over the members of this ensemble.</li>

    <li>Implicit parallelism. The processes that handle messages for
    ensembles are spawned <em>under the hood</em>, and
    programmers interact without having to switch to a <span class=
    "textit">parallel mindset</span>.</li>

    <li>The way the receiver and the operands of a message are treated is
    specified by a set of adverbs.</li>

    <li>The way the result is reduced is specified by a set of gerunds.</li>

    <li>The messages are not reified as for instance in the case of
    <em>Communicating Sequential Processes</em> or
    <em>actors</em>.</li>

    <li>Communication is assumed to be synchronous.</li>

    <li>The processes are not reified as in the case of actor-based
    computing.</li>
  </ul>

  <h1>A Note on the Evaluation Process</h1>

  <p>The <span class="sly">Sly3</span> language is implemented as an extension of a
  Smalltalk Virtual Machine, the RoarVM. The current strategy is that
  whenever a message to an ensemble is detected, a custom message dispatcher
  is launched in order to handle it. Thus, the message is parsed and
  evaluated at runtime. The message is
  analyzed by partitioning the receiver according to its adverb, and pairing
  it with the arguments according to arguments&#8217; adverbs. Then, the actual
  operation is executed in whichever set of operands resulted from the
  previous processing. The final result is reduced according to the gerund.
  When we use the expression <em>according to</em>, it is
  worth to highlight that the actual behavior is encoded in the classes of
  the gerunds an adverbs.</p>

  <p>Below we give as example the implementation of the <code>totallING</code>
  gerund. In the image it is the only method of the class
  <code>Sly3ModTotalling</code>. Notice, that it nothing more but the
  implementation of a simple summing policy.</p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false;">
    ; method of the class Sly3ModTotalling
    reduceForEvaluator: ev
      "Sum the elements in results and return the result.
      Assumes these elements understand +."
      | result results |
      results := ev result.

      results isEmpty ifTrue:
        [ self error: 'No members, how should we handle?  proceed for nil'.  
          ^nil ].

      result := 0.
      results do: [ :each | result := each + result ].
      ev result: result
  </pre></div>



  <p>Below we give the code for the two relevant method of the
  <code>Sly3ModCollectionly</code> class that implements the
  <code>collectionLY</code> adverb in Sly3. Although it is necessary to deeply
  understand the behavior of the process of evaluating a message in order to
  understand this code, at least we can have an intuition that what is
  happening at some point is that a collection is created and returned (see
  line 17). Eventually, this is how the creation
  of a collection from an ensemble (which is what <code>collectionLY</code> does)
  is implemented.</p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false;">
    ; methods of the class Sly3ModCollectionly
    amendOperandTuples: operandTuplesIncludingThisOne
    	| ens |
    	ens := (operandTuplesIncludingThisOne collect: [:ot | ot last]).
    	^ operandTuplesIncludingThisOne collect: [:ot |
    		  ot copy removeLast; addLast: ens; yourself]


    extendOperandTuples: operandTuplesSoFar 
               operand: operand
               membersOrNil: operandMembers
    	| mems |
    	mems := operandMembers ifNil: [operand] 
                                ifNotNil: [operandMembers].
    	^ operandTuplesSoFar
    	    ifEmpty: [OrderedCollection with: 
                             (OrderedCollection with: mems)]
    	    ifNotEmpty: [ operandTuplesSoFar collect: 
                               [:tuple | tuple copy addLast: mems; yourself]]
  </pre></div>

  <p>Therefore, each modifier in <span class="sly">Sly3</span> is self descriptive and
  fully determines the impact that their presence provokes on the evaluation
  process.</p>

  <h1>Implementing MapReduce in <span class="sly">Sly3</span></h1>

  <p>In order to show an example of how to use <span class="sly">Sly3</span>, we have
  implemented a <em>naive</em> MapReduce framework. Take a look at the
  <a href="http://soft.vub.ac.be/~tvcutsem/multicore/index.html">course notes</a>
  for an Erlang implementation of the
  <a href="http://soft.vub.ac.be/~tvcutsem/multicore/6-MapReduce.zip">same examples</a>.</p>
  
  <p>It is worth to stress that the conciseness of
  the code that we eventually obtain is a consequence of both using
  <span class="sly">Sly3</span> and the application of an Object-oriented approach. The
  framework relies on ensembles that receive messages. By doing that, the
  messages are implicitly sent in parallel, so we do not have to specify this
  in the code. We next discuss the core excerpts of the code.</p>

  <p>Imagine two well-known applications of MapReduce. First, we want to
  count the number of occurrences of words in a set of documents. Another
  application is to know in which documents some words are found. In order to
  do that, the MapReduce paradigm requires us to provide the problem-specific
  knowledge by means of a map procedure and a reduce procedure.</p>

  <p>Since <span class="sly">Sly3</span> being an object-oriented language, we have
  modeled the MapReduce problem-independent behavior as a class
  <code>MapReduce</code>. Any particular implementation has to subclass this
  class and override two abstract methods, namely, <code>mapForKey:value:</code>
  and <code>reduceForKey:values:</code>.</p>

  <p>Facing the problem of counting words in a document, below are the
  methods of the class <code>CountWordsMapReduce</code> that implement this
  behavior in <span class="sly">Sly3</span>.
  Notice that for sakes of simplicity, we have modeled a filesystem as
  a <code>Dictionary</code> whose keys are strings that represent file names
  and whose values are ensembles corresponding to the set of words in a
  file.</p>


  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false;">
    "Specific methods of the class CountWordsMapReduce"
    mapForKey: ignore value: fileName
    	| words |
    	words :=  self consult: fileName.
    	^ words valueLY: [:y| {y. 1}]

    reduceForKey: word values: counts
    	^ {word. counts totallING}

    consult: file
    	^ files at: file
  </pre></div>

  <p>Facing the problem of indexing the texts using the words that they
  contain, below are the methods of the class <code>TextIndexingMapReduce</code>
  that implement this behavior in <span class="sly">Sly3</span>.</p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false;">
    "Specific methods of the class TextIndexingMapReduce"
    mapForKey:  ignore value: fileName
    	|words |
    	words :=   self consult: fileName. 
    	^ words valueLY: [:word| {word. fileName}]

    reduceForKey: word  values: names
    	^ {word. names members asSet}

    consult: file
    	^ files at: file
  </pre></div>
    
  <p>Notice that in both cases, it suffices to use combinations of the
  existing adverbs to achieve the desired functionality (see lines 5 and 8 of the
  first listing and line 5 in the second
  one). Moreover let&#8217;s now analyze the class <code>MapReduce</code>, that
  implements all the <em>machinery</em> of our naive
  MapReduce implementation.</p>

  <div style="padding-top:10px;padding-bottom:10px;padding-left:40px;">
  <pre class="brush: st; toolbar: false;">
    "Specific methods of the class MapReduce"
    dictionaryToList: dict
    	|lst|
    	lst := OrderedCollection new.
    	dict associationsDo: 
              [:assoc| lst add:{assoc key. 
                       Sly3Ensemble 
                         withMembersFrom: assoc value}].
    	^ Sly3Ensemble withMembersFrom: lst

    do: input
    	|dict  nonFlatValues flatValues intermediateValues|
    	nonFlatValues:= input valueLY:  [ :pair |
         self mapForKey: (pair at: 1) value: (pair at: 2)].
    	flatValues := nonFlatValues members 
          inject:  (OrderedCollection new) 
          into: [:acc :cur | 
                  acc addAll: 
                        cur members asOrderedCollection. 
                  acc].
    	dict := self groupValuesByKey: flatValues.
    	intermediateValues:= self dictionaryToList: dict.
    	^ intermediateValues valueLY:
           [ :pair | self reduceForKey: (pair at: 1) 
                          values: (pair at: 2) ]

    groupValuesByKey: keyValues
    | dict|
    dict := Dictionary new.
    keyValues do:[:keyValue |
    	| key value |
    	key := keyValue at: 1.
    	value := keyValue at: 2.
    	(dict includesKey: key)
          ifTrue: 
            [(dict at:key) add: value]
          ifFalse: 
            [dict at: key 
                  put: (OrderedCollection newFrom: {value})] .
    	].
    ^ dict

    mapForKey: key value: value
    	self subclassResponsibility.

    reduceForKey: key values: values
    	self subclassResponsibility.
  </pre></div>
    
    
  <p>As it is possible to see in lines 9, 13 or 23 of the above code,
  the framework itself also profits from the fact that the data structures
  that are being passed are ensembles. By having ensembles as the main
  element being passed around, it is possible to have implicit parallel
  behavior, which is the key of the MapReduce approach. Evidently, in this
  case we are discussing a very limited version of MapReduce meant to be used
  on a single computer, but it is still useful to show how the implicit
  parallelism in <span class="sly">Sly3</span> works.</p>

  <h1>Conclusions</h1>

  <p>In the spectrum of language abstractions for dealing with parallelism
  and concurrency, <span class="sly">Sly3</span> is a language that has opted for a
  conservative style, in the sense that it is a specific element of the
  language (an ensemble) the one that is subject of parallelism. On the other
  hand, the stress has been put on giving a set of tools to programmers,
  enabling them to combine these tools. For customized strategies, it is the
  impression of the author of this article that the level of granularity is
  too coarse-grained. Although it is conceivable to extend the set of adverbs
  and gerunds by extending the hierarchy aforementioned, this implies to
  understand the <span class="sly">Sly3</span> implementation in very detail, something
  that we most likely do not expect from application programmers. It is
  possible to think of a meta-programming framework that could <em>inject</em> custom functionalities in the language, lowering the
  complexity for extending the set of primitives.</p>

  <p>Regarding the approach to parallelism, it is implicit and synchronous.
  Programmers are not aware of how computations are spawned or scheduled, and
  the only means they have to initiate parallel computations is by using
  ensembles.</p>

  <p>As regards to the syntax, <span class="sly">Sly3</span> uses decorated keyword
  based messages to model the way the message is handled by the virtual
  machine. Although it is conceivable that this schema can be improved, there
  are some problems originated from the fact that adverbs can decorate
  receivers, arguments, and the overall strategy. If we add to this
  complexity the gerunds, it is clear that it is difficult to express these
  multidimensional facets using a textual syntax.</p>

  <p>To sum up, <span class="sly">Sly3</span> is a language that incorporates in its
  design a series of patterns to deal with parallelism, but the mechanism for
  extending the set of parallel primitives could be reconsidered, in order to
  reduce the complexity of extending <span class="sly">Sly3</span>. However, the
  MapReduce example has shown that it is possible to concisely express
  complex patterns of interactions in <span class="sly">Sly3</span>, as soon as these
  patterns fall within the give set of <span class="sly">Sly3</span>&#8216;s primitives.</p>

  <h2>Bibliography</h2>

  <dl>
    <dt><a name="Ungar2010" id="Ungar2010">UA10</a></dt>

    <dd>David Ungar and Sam S. Adams.<br />
    <a href="http://domino.research.ibm.com/library/cyberdig.nsf/papers/9AA77D5888C803A9852577920058A645">Harnessing emergence for manycore programming: early experience
    integrating ensembles, adverbs, and object-based inheritance.</a><br />
    In <em>Proceedings of the ACM international conference companion on
    Object oriented programming systems languages and applications
    companion</em>, SPLASH &#8217;10, pages 19-26, New York, NY, USA, 2010.
    ACM.</dd>
  </dl>

<script type="text/javascript">SyntaxHighlighter.all();</script>

]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2011/08/the-sly3-programming-language/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RoarVM: The Manycore SqueakVM</title>
		<link>http://soft.vub.ac.be/~smarr/2010/11/roarvm-the-manycore-squeakvm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=roarvm-the-manycore-squeakvm</link>
		<comments>http://soft.vub.ac.be/~smarr/2010/11/roarvm-the-manycore-squeakvm/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 23:40:41 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Renaissance]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Manycore]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[RoarVM]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=382</guid>
		<description><![CDATA[We are happy to announce, now officially, RoarVM: the first single-image manycore virtual machine for Smalltalk. The RoarVM supports the parallel execution of Smalltalk programs on x86 compatible multicore systems and Tilera TILE64-based manycore systems. It is tested with standard Squeak 4.1 closure-enabled images, and with a stripped down version of a MVC-based Squeak 3.7 image. Support for Pharo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/smarr/RoarVM/"><img class="alignleft" title="RoarVM: The Manycore SqueakVM" src="http://github.com/smarr/RoarVM/raw/master/misc/RoarVM-logo-full.jpg" alt="" width="150" height="150" /></a>We are happy to announce, now officially, RoarVM: the first single-image manycore virtual machine for Smalltalk.</p>
<p>The RoarVM supports the parallel execution of Smalltalk programs on x86 compatible multicore systems and Tilera TILE64-based manycore systems. It is tested with standard Squeak 4.1 closure-enabled images, and with a stripped down version of a MVC-based Squeak 3.7 image. Support for Pharo 1.2 is currently limited to 1 core, but we are working on it.</p>
<p>A small teaser:<br /> 1 core   66286897 bytecodes/sec;  2910474 sends/sec<br /> 8 cores 470588235 bytecodes/sec; 19825677 sends/sec</p>
<p>RoarVM is based on the work of David Ungar and Sam S. Adams at IBM Research. The port to x86 multicore systems was done by me. They open-sourced their VM, formerly know as Renaissance VM (RVM), under the <a href="http://www.eclipse.org/legal/epl-v10.html">Eclipse Public License</a>. Official announcement of the IBM source code release: <a href="http://soft.vub.ac.be/~smarr/rvm-open-source-release/">http://soft.vub.ac.be/~smarr/rvm-open-source-release/</a></p>
<p><a href="http://soft.vub.ac.be/~smarr/rvm-open-source-release/"></a>The source code of the RoarVM has been released as open source to enable the Smalltalk community to evaluate the ideas and possibly integrate them into existing systems. So, the RoarVM is meant to experiment with Smalltalk systems on multi- and manycore machines.</p>
<p>The open source project, and downloads can also be found on GitHub:</p>
<p><a href="http://github.com/smarr/RoarVM">http://github.com/smarr/RoarVM</a><br /> <a href="http://github.com/smarr/RoarVM/downloads">http://github.com/smarr/RoarVM/downloads</a></p>
<p><a href="http://github.com/smarr/RoarVM/downloads"></a>For more detailed information, please refer to the <a href="http://github.com/smarr/RoarVM/blob/master/README.rst">README</a> file.<br />Instructions to compile the RoarVM on Linux and OS X can be found in the <a href="http://github.com/smarr/RoarVM/blob/master/INSTALL.rst">INSTALL</a> file.<br />Windows is currently not supported, however, there are good chances that it<br />will work with cygwin or pthreads for win32, but that has not be verified in<br />anyway. If you feel brave, please give it a shot and report back.<br /><br />If the community does not object, we would like to occupy the<br /><a href="mailto:vm-dev@lists.squeakfoundation.org">vm-dev@lists.squeakfoundation.org</a> mailinglist for related discussions. So, if<br />you run into any trouble while experimenting with the RoarVM, do not hesitate<br />to report any problems and ask any questions.<br /><br />You can also follow us on Twitter <a href="http://twitter.com/roarvm">@roarvm</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2010/11/roarvm-the-manycore-squeakvm/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>RVM Open Sourced, Soon to be known as RoarVM</title>
		<link>http://soft.vub.ac.be/~smarr/2010/11/rvm-open-sourced-soon-to-be-known-as-roarvm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rvm-open-sourced-soon-to-be-known-as-roarvm</link>
		<comments>http://soft.vub.ac.be/~smarr/2010/11/rvm-open-sourced-soon-to-be-known-as-roarvm/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 22:12:49 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Renaissance]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[Manycore]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[RoarVM]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=377</guid>
		<description><![CDATA[Just a brief heads up before the actual announcement of RoarVM. The Renaissance VM has been open sourced. The official contribution of IBM Research to the open source community can be found here: The Renaissance Virtual Machine: Open Source Release Announcement. The code is already posted to GitHub and somewhat extended to make it actually useful. Please [...]]]></description>
			<content:encoded><![CDATA[<p>Just a brief heads up before the actual announcement of RoarVM.</p>
<p>The Renaissance VM has been open sourced. The official contribution of IBM Research to the open source community can be found here: <a href="http://soft.vub.ac.be/~smarr/rvm-open-source-release/">The Renaissance Virtual Machine: Open Source Release Announcement</a>.</p>
<p>The code is already posted to <a href="http://github.com/smarr/RoarVM">GitHub</a> and somewhat extended to make it actually useful. Please feel free to head over to <a href="http://github.com/smarr/RoarVM">http://github.com/smarr/RoarVM</a>, play with the code, try the VM with your image, and report back.</p>
<p>The official announcement will be send out in the next couple of days, but any feedback we could get before hand would allow to fix issues before the community gets started with the VM.</p>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2010/11/rvm-open-sourced-soon-to-be-known-as-roarvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Towards an Actor-based Concurrent Machine Model</title>
		<link>http://soft.vub.ac.be/~smarr/2010/02/towards-an-actor-based-concurrent-machine-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=towards-an-actor-based-concurrent-machine-model</link>
		<comments>http://soft.vub.ac.be/~smarr/2010/02/towards-an-actor-based-concurrent-machine-model/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 23:19:08 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Actors]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[Manycore]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[paper]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VMs]]></category>
		<category><![CDATA[workshop]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=289</guid>
		<description><![CDATA[Already quite a while ago, I was involved in writing a workshop paper about an actor model for virtual machines. Actually, the main idea was to find a concurrency model for a VM which supports multi-dimensional separation of concerns. However, AOP is not that interesting for me at the moment, so I am focussing on [...]]]></description>
			<content:encoded><![CDATA[<p>Already quite a while ago, I was involved in writing a workshop paper about an actor model for virtual machines. Actually, the main idea was to find a concurrency model for a VM which supports multi-dimensional separation of concerns. However, AOP is not that interesting for me at the moment, so I am focussing on the concurrency, especially the actor-based VM model.</p>
<p>After one year, I am back looking at that paper, and it still looks like a great model. Think, I will incorporate it into my manycore VM now <img src='http://soft.vub.ac.be/~smarr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Abstract</h3>
<blockquote>
<p>In this position paper we propose to extend an existing delegation-based machine model with concurrency primitives. The original machine model which is built on the concepts of objects, messages, and delegation, provides support for languages enabling multi-dimensional separation of concerns (MDSOC). We propose to extend this model with an actor-based concurrency model, allowing for both true parallelism as well as lightweight concurrency primitives such as coroutines. In order to demonstrate its expressiveness, we informally describe how three high-level languages supporting different concurrency models can be mapped onto our extended machine model. We also provide an outlook on the extended model&#8217;s potential to support concurrency-related MDSOC features.</p></blockquote>
<ul>
	<li>Towards an Actor-based Concurrent Machine Model, <em>Hans Schippers, Tom Van Cutsem, Stefan Marr, Michael Haupt, Robert Hirschfeld</em>, Proceedings of the fourth workshop on the Implementation, Compilation, Optimization of Object-Oriented Languages, Programs and Systems (ICOOOLPS), New York, NY, USA, ACM (2009), p. 4&#8211;9.</li>
	<li>Paper: <a title="Towards an Actor-based Concurrent Machine Model" href="http://soft.vub.ac.be/~smarr/downloads/icooolps09-schippers.pdf">PDF</a><br /> ©ACM, 2009. This is the author&#8217;s version of the work. It is posted here by permission of ACM for your personal use. Not for redistribution. The definitive version was published in ICOOOLPS’09 July 6, 2009, Genova, Italy. <a href="http://doi.acm.org/10.1145/1565824.1565825">http://doi.acm.org/10.1145/1565824.1565825</a></li>
	<li>BibTex: <a href="http://www.bibsonomy.org/bibtex/243d4b86261eac5a70d28160c493e70d1/gron">BibSonomy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2010/02/towards-an-actor-based-concurrent-machine-model/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to use Pharo/Squeak from the Command-line</title>
		<link>http://soft.vub.ac.be/~smarr/2009/09/how-to-use-pharosqueak-from-the-command-line/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-use-pharosqueak-from-the-command-line</link>
		<comments>http://soft.vub.ac.be/~smarr/2009/09/how-to-use-pharosqueak-from-the-command-line/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 07:54:15 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Benchmarks]]></category>
		<category><![CDATA[Command-line]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Language Shootout]]></category>
		<category><![CDATA[Pharo]]></category>
		<category><![CDATA[Smalltalk]]></category>
		<category><![CDATA[Squeak]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://soft.vub.ac.be/~smarr/?p=254</guid>
		<description><![CDATA[Along the way to measure the performance of a Smalltalk implementation for commodity multi-core systems, I tried to use Pharo as a more convenient development platform. Well, and I failed in the first attempt&#8230; To remind myself and document some of the necessary steps in this environment, I wrote up the following tutorial. Command-line Scripts [...]]]></description>
			<content:encoded><![CDATA[<p>Along the way to measure the performance of a Smalltalk implementation for commodity multi-core systems, I tried to use Pharo as a more convenient development platform. Well, and I failed in the first attempt&#8230;</p>
<p>To remind myself and document some of the necessary steps in this environment, I wrote up the following tutorial.</p>

<h1>Command-line Scripts with a Headless Pharo</h1>


<p>For some tasks like benchmarking and automated testing, an integration
with other tools comes in handy.
For such use cases, Pharo can be used headless, i.e., without its  
graphical
user interface.</p>

<p>This brief tutorial will demonstrate how to use the Debian Language  
Shootout
benchmarks with a fresh Pharo image.</p>

<h2>Step 1: Setup Pharo and a Fresh Image</h2>

<ul>
  <li>download a Pharo image, the sources file, and a VM from the
    <a href="http://www.pharo-project.org/pharo-download">download page</a></li>
  <li> extract all archives in the same folder</li>
  <li> start Pharo, from the commandline, on a MacOSX it should look  
like this:
<code>"Squeak 4.2.1beta1U.app/Contents/MacOS/Squeak VM Opt" \
          pharo1.0-10418-BETAdev09.08.3.image
    </code></li></ul>

<h2>Step 2: Load OSProcess</h2>

<p>For output on the shell, we need an extra package from the SqueakSource
repository.</p>

<p>It can be loaded by simply executing the following code in a workspace  
window:
<br/>
<pre>
ScriptLoader loadLatestPackage: 'OSProcess' from:
'http://www.squeaksource.com/OSProcess'
</pre>

<p>To execute this code snippet, select it and press cmd+d or use the &#8220;do  
it&#8221;
item in the context menu.</p>

<h2>Step 3: Load Common Benchmark Code</h2>

<p>Now we can load the common parts of all shootout benchmarks into our  
image.</p>
<ul>
<li>On way to do this is to grab the code shown <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;lang=squeak&amp;lang2=squeak">here</a></li> and save it to a file called <code>common.st</code>.</li>
  <li>Open the file browser from the Menu -&gt; Tools -&gt; File Browser.</li>
  <li>Select <code>common.st</code> and press <code>filein</code> to load the code.</li></ul>

<p>Now you can close all windows in your image and save and quit it.</p>

<h2>Step 4: Run a Benchmark</h2>
<ul>
<li>Grab the code of a benchmark like <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=fannkuch&amp;lang=squeak&amp;id=1">Fannkuch</a></li>
  <li>Save it to a file named like <code>fannkuch.st</code></li>
  <li>Add a run script to the end of the code in <code>fannkuch.st</code>, like  
this:<br/>
<pre>
    Tests fannkuch.
    SmalltalkImage current snapshot: false andQuit: true.
</pre></li>
  <li>Run it with a headless Pharo:<br/>
<pre>
    "Squeak 4.2.1beta1U.app/Contents/MacOS/Squeak VM Opt" \
        -headless pharo1.0-10418-BETAdev09.08.3.image \
        $PWD/fannkuch.st 6
</pre><br/>
important is here the absolute path to the script, clearly inconvenient and uncommon on the command-line.</li></ul>
]]></content:encoded>
			<wfw:commentRss>http://soft.vub.ac.be/~smarr/2009/09/how-to-use-pharosqueak-from-the-command-line/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

