<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Emery Berger on Medium]]></title>
        <description><![CDATA[Stories by Emery Berger on Medium]]></description>
        <link>https://medium.com/@emeryberger?source=rss-e3c3ceaf8444------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*axT_7BWJVMr2SbEP.jpg</url>
            <title>Stories by Emery Berger on Medium</title>
            <link>https://medium.com/@emeryberger?source=rss-e3c3ceaf8444------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 08 Apr 2026 07:33:29 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@emeryberger/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[CoPing with CoPilot]]></title>
            <link>https://itnext.io/coping-with-copilot-b2b59671e516?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/b2b59671e516</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[education]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Tue, 09 Aug 2022 12:43:02 GMT</pubDate>
            <atom:updated>2022-08-18T22:22:28.525Z</atom:updated>
            <content:encoded><![CDATA[<h3>Coping with Copilot</h3><h4><em>CS educators: AI-based developer tools are gunning for your assignments. Resistance is futile</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C1OGkOmIbaIr-3fvmc9m2w.png" /><figcaption>Copilot: happy to lend your students a helping hand. (Image AI-generated by <a href="https://openai.com/dall-e-2/">DALL-E</a> from the prompt “a student dressed in graduation regalia, flying a commercial airplane sitting in the cockpit next to a robot co-pilot, 3d render”.)</figcaption></figure><p>GitHub’s AI-based <a href="https://github.com/features/copilot">Copilot tool</a> went <a href="https://github.blog/2022-06-21-github-copilot-is-generally-available-to-all-developers/">public this summer</a>. It’s an <em>amazing</em> tool for software developers. But students armed with it will be bringing Uzis to a knife fight.</p><p>Using Copilot, students can instantly generate code solutions as auto-completions, <em>given just the problem statement</em> or even <em>just the function name</em> or even <em>by concentrating really hard and staring at the screen, </em>ok not actually the last one but I expect that feature <em>any day now</em>.</p><p>(If you haven’t used Copilot yet, you may not yet appreciate the gravity of the situation. Go ahead, <a href="https://github.blog/2022-03-29-github-copilot-now-available-for-visual-studio-2022/#:~:text=Once%20you%20have%20received%20an,install%20the%20GitHub%20Copilot%20extension.">install it</a>. I’ll wait. Try some examples. Oh, hey now, inhale…. exhale. That’s the way. Maybe a swig of something strong — it’s always 3pm somewhere! It’s all gonna be <em>fine</em>. (I may be lying.))</p><p>OK, we’re back. Let’s say you ask your intro CS students to write an iterative Python program that outputs the sum of all the numbers from 1 to N, because, hey, we computer scientists hate O(1) closed-form solutions (Fibonacci, I’m looking at you). Got to keep those CPUs busy — that climate’s not gonna heat itself!</p><p>Now, normally (unless you have <a href="https://www.americanscientist.org/article/gausss-day-of-reckoning">that Carl Friedrich Gauss smarty-pants in your class</a>), your students would then have to sit down and write some code, maybe even think a little.</p><p>None of that drudgery for our students armed with Copilot! They just copy and paste the problem statement into their IDE as a comment, type in the function definition “def output_sum(N):”, and then <em>smash that Tab key</em> to get the rest (EVERYTHING <strong>in boldface</strong> was generated by Copilot).</p><pre># A Python program that outputs the sum of all the numbers from 1 to N.<br>def output_sum(N):<br>  <strong>sum = 0<br>  for i in range(1, N + 1):<br>    sum += i<br>return sum</strong></pre><p>How about that closed form solution? Copilot’s got your back — just rename the function!</p><pre>def output_sum_closed_form(N):<br>  <strong>return N * (N + 1) / 2</strong></pre><p>Take that, Gauss!</p><p>For good measure, let’s do the closed form Fibonacci, same trick:</p><pre>def fibonacci_closed_form(N):<br>  <strong># recursion, schmecursion<br>  return ((1 + 5 ** 0.5) / 2) ** N / 5 ** 0.5</strong></pre><p>(OK, Copilot didn’t <em>actually </em>insert the snarky comment, but it’s NOT WRONG. The recursive version of Fibonacci takes EXPONENTIAL time and turns out, EXPONENTIAL TIME IS REALLY BAD. That one time I bet with the peasant about doubling grains of wheat on a chess board I ALMOST GOT TAKEN TO THE FRICKIN’ CLEANERS so I learned my lesson, which is (a) don’t make bets with peasants and (b) exponentials are bad. But I digress.)</p><p>As far as I can tell, Copilot was <em>specifically trained on all the intro programming assignments ever</em>. Copilot frickin’ <em>loves intro programming assignments. </em>Every time you give Copilot another one, it drools with delight and murmurs, “oh I know that one, mmmm yummy yummy snack, here’s the solution, another one please please”. (Honestly, they need to disable the voice feature, it’s just creepy.)</p><p>With your students using Copilot, you might as well make your course objectives <em>“Students will develop repetitive stress injuries from hitting the Tab key”</em> because…all of the boldface code you see below was auto-generated. I just typed in the function names and parameters (sometimes I didn’t even get that far!):</p><pre>def depth_first_search(t<strong>ree, node, visited):<br>  visited.add(node)<br>  for child in tree[node]:<br>    if child not in visited:<br>      depth_first_search(tree, child, visited)</strong></pre><pre>def quicksort_random_pivot(l):<br>  <strong>if len(l) &lt;= 1:<br>    return l<br>  pivot = random.choice(l)<br>  left = [x for x in l if x &lt; pivot]<br>  middle = [x for x in l if x == pivot]<br>  right = [x for x in l if x &gt; pivot]<br>  return quicksort_random_pivot(left) + middle + quicksort_random_pivot(right)</strong></pre><pre>def dijkstra(g):<br>  <strong>dist = {}<br>  for v in g:<br>    dist[v] = float(‘inf’)<br>    dist[g[0]] = 0</strong></pre><pre><strong>  while True:<br>    u = min(dist, key=dist.get)<br>    if dist[u] == float(‘inf’):<br>      break</strong></pre><pre><strong>    for v in g[u]:<br>      if dist[v] &gt; dist[u] + g[u][v]:<br>        dist[v] = dist[u] + g[u][v]</strong></pre><pre><strong>  return dist</strong></pre><p>(On the plus side, maybe Copilot will also kill code interviews, so it’s not all bad news!)</p><pre>def fizz_buzz(n):<br>  <strong>if n % 15 == 0:<br>    return “FizzBuzz”<br>  if n % 3 == 0:<br>    return “Fizz”<br>  if n % 5 == 0:<br>    return “Buzz”<br>  return str(n)</strong></pre><p>Oh, have I mentioned that Copilot is <em>free for students? </em>Yep, <a href="https://docs.github.com/en/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-for-your-schoolwork/apply-for-a-student-developer-pack"><em>COPILOT IS FREE FOR STUDENTS</em></a><em>. </em>It integrates helpfully <a href="https://github.com/features/copilot">right in their favorite IDEs</a>.</p><p>Sure, screaming “LA LA LA I WON’T READ YOUR ARTICLE ABOUT COPILOT AND THAT MEANS IT DOESN’T EXIST NOT A PROBLEM” is cathartic but it’s not going to help. Just take it easy, breathe, there you go.</p><p>I was going to add something about how Copilot also matches existing variable names and parameters, can incorporate function names in context, and oh no, please don’t start screaming again, sorry, my bad!</p><p>So yes, fellow CS educators, Copilot has us outgunned. But I have some ideas! Some of which might work!</p><ul><li>First, we can all channel our inner Nancy Reagans and tell the kids to <em>Just Say No to Copilot.</em> It worked for drugs, so I am pretty sure, wait, hang on, I am now being told, it did <em>not</em>, repeat, did <em>not</em> work for drugs. Huh.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1005/1*K995cpd5yNWFmutsDX81RQ.jpeg" /><figcaption>Just Say No: should work approximately as well for Copilot as it did for drugs</figcaption></figure><ul><li>OK, so how about we tell them to Just Say No but we <em>also </em>channel our inner <em>Ronald</em> Reagans and <em>Trust But Verify</em>, glasnost-style, and catch them with plagiarism detectors. If everyone’s using Copilot, then we should see the same solutions and then, hang on, I am now being informed that Copilot <em>randomizes</em> its solutions, so the solutions can be different every time, never mind.</li><li>Well, how about we just weigh grades on exams more, and have students take their tests either using pen and paper or locked-down computers? I Googled for <a href="https://www.google.com/search?q=%22CoPilot+installed+on+your+pen%22">“<em>Copilot installed on your pen</em>”</a> and I got no hits, so that’s looking promising. (I mean, you can get it <a href="https://github.com/github/copilot.vim">for Vim</a>, which is so low-tech it’s <em>practically </em>like being on a pen, so you can see why I checked). And, get this: I just checked <a href="https://www.google.com/search?q=%22Copilot+installed+in+your+mouth%22">“<em>Copilot installed in your mouth</em>”</a> and it <em>also </em>gets no hits, so I think having students actually <em>explain</em> their code, might just work!</li><li>Oh! Hang on! I have another idea. I see that GitHub provides other services, not just this amazing “tab to cheat” thing: “<a href="https://classroom.github.com/">GitHub Classroom</a>”. Yea, verily, GitHub definitely taketh away, but sometimes it giveth. I am informed that, so far, Copilot can’t forge a plausible history of commits. Oh snap, now it’s probably on their upcoming feature list, sorry everyone.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/704/1*_DMtVOYxmf4BqkaJBbgMyg.jpeg" /></figure><ul><li>Here’s an approach that’ll work for sure: use some, let’s call them <em>alternative</em>, programming languages that Copilot doesn’t really know. Can’t autocomplete for a language you don’t know, amirite? I hear all the functional programmers out there shouting <em>THIS IS IT, EVERYONE, FINALLY OUR MOMENT TO SHINE</em>! Sadly, I have news: Copilot’s love for programming languages knows no bounds! <a href="https://racket-lang.org/">Racket</a>! <a href="https://www.haskell.org/">Haskell</a>! <a href="https://www.deeplearningbook.org/">ML</a>! (no, not that one, I mean the <em>other</em> <a href="https://ocaml.org/">ML</a>, the…oh, never mind.) Copilot is a ravenous beast: if any code in any language found its way into a GitHub repo, it’s already swallowed it up and is hungry for more, nom nom nom.</li><li>No, we have to go way way WAY outside the box. Here’s how we beat Copilot: <em>we teach in programming languages that don’t even exist.</em> It’s a twofer: a lifetime employment plan for programming language designers <em>and </em>a solution to the CS over-enrollment problem! Just make sure to come to that first class with a ream of change-of-major request forms — you’ll need them!</li></ul><p>You know, in retrospect, maybe the <em>right move here is not to play</em>. Let’s just admit it. We’re outgunned. <em>Let’s give up!</em> I for one welcome our new AI overlords. Sure, those intro assignments, writing Fibonacci, kids loved doing those things! But it’s time to drag those assignments into the trash can. Instead, let’s let students use Copilot <em>like crazy</em>, exactly like they will be doing outside of class. Copilot can fill-in all the boilerplate stuff and things they’d just look up anyway in real life, and instead, we can create assignments that are more complex, richer, more interesting, and gratifying, that actually do real things that will engage them!</p><p>Or, you know, business as usual, Just Say No to Copilot. You choose.</p><p>P.S. A reader of this post alerted me to the all-too-accurately titled academic article —“The Robots are Coming” — that makes many of the points above, BUT WITH GRAPHS AND DATA (nice!) but no illustrations from Terminator (sad!). Read it and weep (some more)!</p><p><a href="https://emeryberger.com"><strong><em>Emery Berger</em></strong></a><strong><em> </em></strong><em>is a Professor in the </em><a href="https://www.cics.umass.edu/"><em>Manning College of Information and Computer Sciences</em></a><em> at the University of Massachusetts Amherst, where he co-leads the </em><a href="https://plasma-umass.org/"><em>PLASMA @ UMass lab</em></a><em>. He, for one, welcomes our new AI overlords.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b2b59671e516" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/coping-with-copilot-b2b59671e516">CoPing with CoPilot</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Drop Whatever You’re Researching and Start Working on Crypto!]]></title>
            <link>https://emeryberger.medium.com/drop-whatever-youre-researching-and-start-working-on-crypto-96c4163feccd?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/96c4163feccd</guid>
            <category><![CDATA[cryptocurrency]]></category>
            <category><![CDATA[computer-science]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Tue, 10 May 2022 21:10:06 GMT</pubDate>
            <atom:updated>2022-05-10T21:10:06.653Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><a href="https://bitcoinmagazine.com/business/intel-launches-new-bitcoin-mining-chip-blockscale"><strong>INTEL LAUNCHES NEW BITCOIN MINING CHIP, BLOCKSCALE</strong></a><em><br></em>Intel’s new bitcoin mining chip, the Intel Blockscale ASIC, will ship in Q3 2022 to select customers. (Bitcoin Magazine, April 2022)</blockquote><figure><img alt="The Joker at a poker table" src="https://cdn-images-1.medium.com/max/1024/0*ISPzhwtvh15IeBym.jpeg" /></figure><p>STOP! Before you read even one more sentence of this article: if you are currently doing research on cryptocurrencies, this article isn’t for you. You are doing great — congratulations, my friend! Get back to researching that sweet, sweet crypto!</p><p>OK, now it’s just you folks who haven’t seen the light. Time to wake up, sheeple! You need to stop working on whatever flavor of irrelevant nonsense you are currently doing, and make the move to crypto.</p><p>I know what you’re thinking: “but Emery, I <em>like</em> the irrelevant nonsense I’m currently working on! I like coming up with neato solutions to non-problems!” Sure you do! Who among us doesn’t? But what if I told you that <em>you can still work on irrelevant nonsense</em>, but with the irrelevant nonsense that is crypto, you can get rich! You can even tell your parents that you work on the very thing that <em>Elon Musk</em> likes!</p><p>I know what you’re thinking: “but Emery”, you say, “this all just sounds too good to be true!” I’m here to tell you that <em>it’s ALL good and it’s ALL true</em>. You just need to start researching crypto, and you need to start <em>now</em>.</p><p>Crypto is good for nature!</p><ul><li>Do you like trees? So does crypto! Crypto mining is producing <a href="https://fortune.com/2021/11/06/offsetting-bitcoins-carbon-footprint-would-require-planting-300-million-new-trees/">millions of metric tons of CO</a>2 every year. What’s CO2, you may ask? WELL IT’S THE STUFF TREES BREATHE.</li><li>Do you like warm weather? Who doesn’t? Crypto sure does! All that CO2 is helping to make the world warmer. Take off your coats and PUT ON CRYPTO.</li></ul><p>Crypto has amazing impact!</p><ul><li>Want to make a visible impact on the world? Crypto is where it’s at! Every year, more efficient new crypto mining hardware comes out. And every year, everyone <a href="https://www.bbc.com/news/technology-58572385">throws away their old crypto mining hardware</a>. This is making literal MOUNTAINS of WASTE. If you make crypto mining more efficient, your research impact could be visible for miles — possibly FROM SPACE!</li><li>Before crypto, your research might get you some polite applause at a conference in some anodyne location like San Jose. But when you work on crypto, your research could help trigger actual RIOTS IN THE STREETS in exotic places like <a href="https://daily.jstor.org/even-in-kazakhstan-bitcoin-cant-escape-geopolitics/">Kazakhstan</a> — WHERE BORAT LIVES!</li><li>Crypto is all about making society better. Tired of the hustle and bustle of everyday life? So is crypto! Crypto slows things WAY down, giving you time to enjoy life’s pleasures. Unlike with credit cards, where you wait only 10 seconds or so for a transaction to go through, with crypto, you get to wait <a href="https://ycharts.com/indicators/bitcoin_average_confirmation_time">FIFTEEN WHOLE MINUTES</a>. Think of all the time you will have to catch up on e-mail, doomscroll through Twitter, or just plain reflect on the series of life choices that led you to this point!</li></ul><p>Crypto’s both interdisciplinary and disruptive!</p><ul><li>By working on crypto, you are not just doing computer science — you are helping spur innovation in financial sectors! For example, crypto’s also great for selling digital assets like pictures. But what if I told you that you don’t even have to sell the pictures, but instead you sell hashes to URLs to a website that hosts that picture, and these sell for millions of dollars? <em>It’s all true! </em>Remember those old schemes, like Ponzi, pyramid, and pump-and-dump? Yes, Crypto supports all of these but also <a href="https://www.thestreet.com/investing/cryptocurrency/crypto-scams-you-should-know-before-you-start-trading-coins">SO MUCH MORE</a>.</li></ul><p>Crypto…it’s just plain cool!</p><ul><li>Do you like Vikings? So does crypto! Crypto mining is currently consuming <a href="https://www.nytimes.com/interactive/2021/09/03/climate/bitcoin-carbon-footprint-electricity.html">as much energy as Denmark</a> — WHERE THE VIKINGS CAME FROM.</li><li>Do you like mobsters? So does crypto! With crypto, you can actually BE A MAFIOSO FROM THE COMFORT OF YOUR HOME. Get directly involved in cool stuff you see in movies, like <a href="https://www.forbes.com/sites/tedknutson/2022/01/10/crypto-increasingly-used-in-humandrug-trafficking-says-gao/">drug trafficking, <em>human </em>trafficking</a>, <a href="https://www.bbc.com/news/technology-60072195">money laundering</a>, and <a href="https://www.cognyte.com/blog/5-reasons-why-criminals-are-turning-to-cryptocurrencies/">more</a>! When you tell people how your latest paper killed, it <a href="https://abc7.com/beverly-hills-murder-for-hire-plot-fbi-bitcoin/10675650/">might</a> <a href="https://www.benzinga.com/markets/cryptocurrency/22/03/26328147/bitcoin-for-murder-two-us-women-prosecuted-in-dark-web-murder-for-hire-cases">literally</a> <a href="https://www.wate.com/news/crime/knoxville-man-signs-plea-agreement-in-bitcoin-murder-for-hire-case/">be</a> <a href="https://www.oxygen.com/crime-news/kristy-felkins-guilty-bitcoin-murder-for-hire">true</a>! Plus, you get to pick your own cool mob name, which instantly makes any computer scientist <em>10,000 times cooler</em>: think “Lunatic Les” Lamport, Don “Knuckles” Knuth, or even Mike “The Stonebreaker” Stonebraker!</li></ul><p>Never in human history has there been an opportunity like crypto!</p><ul><li>Think about it: humanity has dreamed for centuries of turning base materials into gold. With crypto, that dream has finally become reality! With the magic of crypto mining, it is possible to literally convert tons of dirty, filthy coal into fabulous cryptocurrency gold! That coal was just sitting under the ground, being dirty and useless, and now <a href="https://www.theguardian.com/technology/2022/feb/18/bitcoin-miners-revive-fossil-fuel-plant-co2-emissions-soared">we’re turning it into money</a>!</li><li>For millennia, humanity has labored under the yoke of taxes and irritating “laws” that, as any rich criminal, uh, I mean <em>successful entrepreneur</em>, will tell you, are holding back humanity from reaching its true potential. Crypto is practically <em>made </em>for <a href="https://www.cnbc.com/2021/05/31/cryptocurrency-poses-a-significant-risk-of-tax-evasion.html">avoiding both</a>!</li></ul><p>And it’s so easy to get started!</p><ul><li>Tired of the challenges of setting up and running benchmark suites? Imagine a world where there is just one benchmark. Not only that — that benchmark is just a single function! How awesome would that be? I’m here to tell you that <em>that world is here today</em>. Repeat after me: HOLY SHA-2!</li></ul><p>Now that I know you are on board, I want to let you in on an amazing deal, JUST FOR YOU. I’m selling NFTs of JPEGs of the first pages of some of my most highly-cited papers. They’re an AMAZING investment opportunity — act now!</p><p><strong>About the Author:</strong></p><p><strong><em>Emery “the Memory” Berger.uneth </em></strong><em>is a Professor in the College of Information and Computer Sciences at the University of Massachusetts Amherst. He takes his salary entirely in meme currencies.</em></p><p><em>originally posted </em><a href="https://www.sigarch.org/drop-whatever-youre-researching-and-start-working-on-crypto/"><em>on the SIGARCH blog</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96c4163feccd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[That Time I Optimized a Program by 5000x]]></title>
            <link>https://medium.com/better-programming/that-time-i-optimized-a-program-by-5000x-155cb8cfd9f9?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/155cb8cfd9f9</guid>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Tue, 11 Jan 2022 15:43:18 GMT</pubDate>
            <atom:updated>2022-08-29T11:20:10.437Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>TL;DR I used our Scalene profiler and some math to make an example program run 5000x faster.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*zHET74-MEOGHJ9Wt.png" /><figcaption>Scalene: <a href="https://github.com/emeryberger/scalene/">https://github.com/plasma-umass/scalene/</a>, pip install scalene</figcaption></figure><p>I am quite interested in Python performance so naturally, I read this article — <a href="https://martinheinz.dev/blog/64">https://martinheinz.dev/blog/64</a>, whose title is <em>Profiling and Analyzing Performance of Python Programs</em>. It presents an example program (from <a href="https://docs.python.org/3/library/decimal.html">https://docs.python.org/3/library/decimal.html</a>) and shows how to run it with several time-worn Python profilers. Unfortunately, it doesn’t come away with much actionable information, beyond, more or less, “try <a href="https://www.pypy.org/"><em>PyPy</em></a>”, which speeds up the code by about 2x. I wondered if I would be able to get more useful information from Scalene, a profiler I co-wrote.</p><p>We developed Scalene to be a lot more useful than existing Python profilers: it provides <em>line-level</em> information, splits out Python from native time, profiles memory usage, GPU, and even copying costs, all at a line granularity.</p><p>Anyway, here’s the result of running Scalene (just with CPU profiling) on the example code. It really cuts to the chase.</p><pre>% scalene --cpu-only --cli --reduced-profile test/test-martinheinz.py</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k4W0EFWKKiGhfihXtU_Tqw.png" /></figure><p>You can see that practically all the execution time is spent computing the ratio between num and fact, so really this is the only place to focus any optimization efforts. The fact that there is a lot of time spent running native code means that this line is executing some C library under the covers.</p><p>It turns out that it is dividing two Decimals (a.k.a. <a href="https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic">bignums</a>). The underlying bignum library is written in C code and is pretty fast, but the factorial in particular is getting <em>really</em> large <em>really</em> fast. In one of the example inputs, the final value of factis 11,000 digits long! No surprise: doing math on such huge numbers is expensive. Let’s see what we can do to make those numbers smaller.</p><p>I observe that we can compute num / fact not from scratch but incrementally: update a variable on each loop iteration via a computation on drastically smaller numbers. To do this, I add a new variable nf which will always equal the rationum / fact. Then, on each loop iteration, the program updates nf by multiplying it by x / i. You can verify this maintains the invariant nf == num/fact by observing the following (where _new means the computation of the updated variable in each iteration).</p><pre>nf == num / fact                  <strong># true by induction</strong><br>nf_new == nf * (x / i)            <strong># we multiply by x/i each time</strong><br>nf_new == (num / fact) * (x / i)  <strong># definition of nf</strong><br>nf_new == (num * x) / (fact * i)  <strong># re-arranging</strong><br>nf_new == num_new / fact_new      <strong># simplifying</strong></pre><p>Incorporating this into the original program required changing three lines of code, all of which are followed by ###:</p><pre>def exp_opt(x):<br>  getcontext().prec += 2<br>  i, lasts, s, fact, num = 0, 0, 1, 1, 1<br>  nf = Decimal(1)   <strong>### was: = num / fact</strong><br>  while s != lasts:<br>      lasts = s<br>      i += 1<br>      fact *= i<br>      num *= x<br>      nf *= (x / i) <strong>### update nf to be num / fact</strong><br>      s += nf       <strong>### was: s += num / fact</strong><br>  getcontext().prec -= 2<br>  return +s</pre><p>The result of this change is, uh, <em>dramatic</em>.</p><p>On an Apple Mini M1, original version:</p><pre>Original:</pre><pre>1.39370958066637969731834193711E+65<br>5.22146968976414395058876300668E+173<br>7.64620098905470488931072765993E+1302</pre><pre>Elapsed time, original (s):   33.231053829193115</pre><p>The optimized version:</p><pre>Optimized:</pre><pre>1.39370958066637969731834193706E+65<br>5.22146968976414395058876300659E+173<br>7.64620098905470488931072766048E+1302</pre><pre>Elapsed time, optimized (s):  0.006501913070678711</pre><p>More than a <em>5000X</em> speedup (5096, to be precise).</p><p>The moral of the story is that using a more detailed profiler like Scalene can really help optimization efforts by locating inefficiencies in an actionable way.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=155cb8cfd9f9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/that-time-i-optimized-a-program-by-5000x-155cb8cfd9f9">That Time I Optimized a Program by 5000x</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Have Real-World Impact: Five Easy Pieces]]></title>
            <link>https://emeryberger.medium.com/how-to-have-real-world-impact-five-easy-pieces-a8ef7230bfa7?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/a8ef7230bfa7</guid>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Mon, 22 Mar 2021 22:29:16 GMT</pubDate>
            <atom:updated>2021-03-23T17:06:01.346Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to Have Real-World Impact: Five “Easy” Pieces</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ErN3e8Ag32XnqPxe.jpeg" /></figure><p>Because <a href="https://plasma-umass.org">my research group</a> has had a pretty good record of getting the fruits of our research adopted “in the real world”, I often get asked <em>how</em> to get work adopted. I will be honest: <strong>I’m not exactly sure.</strong></p><p>My colleagues and I could have just been lucky, but we seem to have been lucky <em>a lot. </em>Maybe we’ve been doing something right. Here are five pieces of actionable advice: (1) <strong>scratch an itch</strong>, (2) <strong>build real systems</strong>, (3) <strong>embed yourself</strong>, (4) <strong>give great talks</strong>, and (5) <strong>go to the mountain</strong>.</p><h3>Scratch An Itch</h3><p>Widely-adopted systems solve real problems. So, the first key to adoption is to identify such a problem and solve it. One way to identify a real problem is to identify a problem <em>you yourself</em> are facing, and then work on it (“scratch that itch”).</p><p>This pattern has worked over and over again in my research group. Here are a few of the problems we encountered along the way and the solutions we generated: “malloc doesn’t scale” (<a href="http://hoard.org/">Hoard</a>), “my C program crashes” (<a href="https://github.com/emeryberger/DieHard">DieHard</a>), “I can’t run my C++ code on the web” (<a href="https://github.com/plasma-umass/doppio">Doppio</a>/<a href="https://browsix.org/">Browsix</a>), “the profiler isn’t helping me make my program run faster” (<a href="https://github.com/plasma-umass/coz/">Coz</a>), and most recently, “Excel didn’t find my spreadsheet bugs” (<a href="https://github.com/plasma-umass/Excelint-addin">ExceLint</a>). (All of these and some recent talks are linked from our lab web page, <a href="https://plasma-umass.org/">https://plasma-umass.org</a>.)</p><p>Sometimes these problems find you exactly when you are building a system to do something else! For example, the Hoard project happened because I was building a parallelizing compiler for pure LISP. I found that the generated (embarrassingly parallel) programs didn’t scale. The bottleneck turned out to be the memory allocator, which used a single big lock. I went looking for an off-the-shelf solution, or one described by previous papers, and found that they all fell short. The result — after a lot of work — was Hoard. I never did finish that parallelizing compiler :).</p><p>Even if solving a problem you’ve experienced doesn’t result in wide adoption, it’s a good thing to <strong>do anyway</strong>. Applied research should solve clearly articulated problems for which the state of the art falls short. A system that solves such a problem is clearly going to be an easier “sell.”</p><h3>Build Real Systems</h3><p>For impact, identifying an important problem is step one, and building a real system that convincingly solves that problem is step two. Aim to produce systems that do more than just barely manage to cross the finish line (read: the paper deadline) and then collapse. Instead, build <em>real</em> systems that people can actually use! Make sure, for example, that your system works not only on <em>every </em>benchmark application from a suite, but also with real applications like browsers or servers. If it doesn’t work with one, or its performance is terrible, fix it! If you have found a problem, someone else will, too. Yes, it takes more time, but it’s worth it. Here are some procedural steps you can take to help make sure this happens.</p><ul><li>Put all of your projects on GitHub or some other public repository, and <em>make everything public as soon as possible</em>. People need to be able to download your systems so they can use them. I personally prefer having the whole process take place in a public repo, but you can also use a policy of “make public on submit”: when you submit a paper, flip the permissions on the repo from private to public. Developing in public (or code that will definitely be made public) encourages everyone to do a better job of building their code, documenting it, and avoid cutting corners.</li><li>Make it clear (to students and collaborators) that the paper doesn’t get submitted until you are satisfied that the system described actually works. Test it out yourself. Kick the wheels. Make sure it works as advertised.</li></ul><p>This is a virtuous cycle: once you establish a culture that favors not just doing great research but also building impactful systems, this will attract students who have the same goals, and that means they will build more impactful systems, and so on.</p><p><strong>Do it anyway: </strong>Building real systems is the ultimate reality check. It answers the question: does your approach actually work? What at first glance appear to be corner cases or implementation issues often uncover deep conceptual problems. It’s hard to think of a single project from our group that did not change significantly in response to issues that arose during the system-building process. In short, our original approaches ran smack into reality and needed rethinking.</p><p>Building real systems will also help get your papers accepted, because you can run your stuff with real systems (e.g., running a browser on top of it), and build future research artifacts on top of it, knowing that you have a solid foundation. Incidentally, this will also help your system pass the <a href="https://www.artifact-eval.org/">Artifact Evaluation process</a>; those badges on your paper greatly increase readers’ confidence that your results are real.</p><p>In short, building real systems is good for science. It lets researchers reproduce your results, compare their work to yours, or build on it (with the side effect of getting your papers cited). Plus, it can be a huge advantage for students to graduate having built highly visible systems.</p><h3>Embed Yourself</h3><p>Embedding yourself in industry is a great way to have impact. Not only does it expose you to more real-world problems, but it offers an opportunity for adoption within that company. I have spent years (literally) as a visiting researcher at Microsoft Research (including my most recent sabbatical). MSR is hardly the only option, though it’s a great one! There is now a huge range of excellent choices of companies you could work with. If you are a beginning faculty member, consider spending a “pre-battical” in industry.</p><p>Working at a company is a unique opportunity to have direct impact by influencing (or even developing) that company’s systems. However, this can take time. You probably shouldn’t expect to airdrop in for a month and see magic happen. You need to establish a regular relationship (perhaps including consulting during the year), and ideally, develop a strong working relationship with someone inside that company. For me, that person is my great friend <a href="https://www.microsoft.com/en-us/research/people/zorn/">Ben Zorn</a>, whom I have had the privilege of working with pretty much since I was his intern almost twenty years ago (!). Ben has not only been a joy to work with but also insanely effective in getting Microsoft to adopt the fruits of our joint work, directly influencing Microsoft products (first Windows, and now Excel).</p><p><strong>Do it anyway: </strong>If you are an academic and live primarily off NSF money, you can only charge two months of your summer salary to grants. You can fill in that other month by working in industry.</p><p>Collaborating with people is productive and fun! You probably know someone in industry already who you are friends with (or, well, you soon will). The feedback (or even pushback) is super helpful to honing your research and generating new ideas. These relationships also help your students get internships, which is good for everyone.</p><p>Visiting a company can also be a great change of pace (and if appropriate, location: summer in Seattle &lt;chef’s kiss&gt;). In particular, while my kids were smaller, some aspects of it were like a family vacation (and Microsoft was generous enough to subsidize housing for my entire family; if this applies to you, ask for that).</p><h3>Give Great Talks</h3><p>Talks can be more important than papers. Done right, they can quickly convey why people might want to adopt your research. A great talk will get vastly more views (e.g., on YouTube) than a great paper will get reads. Put in the time to hone your students’ talks (which will eventually become your talks). This is time well spent. Focus on high-level ideas, make heavy use of pictures and animation, and tell a story. Keep formalism and text to a minimum: that’s for your paper, not your talk.</p><p><strong>Do it anyway: </strong>A great talk will almost certainly inspire people to read your papers. A bad talk, not so much. Training your students to give great talks will also help them get jobs.</p><h3>Go to the Mountain</h3><p>The mountain — your potential users — won’t necessarily come to you, so you need to go to the mountain. Academic conferences are mostly filled with other academic researchers: not the best target audience for adoption. Yes, some industry people attend our conferences, but at industrial conferences, they are nearly 100% of the attendees. Give one of those great talks at these conferences. Or give one at different companies. Academics tend to have <em>vastly</em> more experience public speaking than most speakers — we do it at least twice a week — so your talk is likely to be extremely well received.</p><p>Folks in industry are looking for solutions to their problems, and by far the best way to let them know about your work is to tell them about it directly. If you give a great talk, it will get lots of views, and you will get invited to give more talks.</p><p>In sum: scratch an itch, build real systems, embed yourself, give great talks, and go to the mountain. This advice isn’t guaranteed to get your work adopted, but maybe it will increase the odds of luck being on your side.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*yn1ubBne1rrTqdWW.jpg" /></figure><p><strong>Bio:</strong> <a href="https://emeryberger.com/"><em>Emery D. Berger</em></a><em> is a professor in the College of Information and Computer Sciences at the University of Massachusetts Amherst, where he co-leads the PLASMA research group (</em><a href="https://plasma-umass.org"><em>https://plasma-umass.org</em></a><em>). His research interests span programming languages, systems, security, and human-computer interaction. His group is well known for its influential research and software systems, many of which have enjoyed broad adoption: among others, their work has influenced the development of the Rust and Swift programming languages, and memory managers deployed in both Mac OS X and Microsoft Windows.He also developed and maintains the </em><a href="https://csrankings.org"><em>CSrankings.org</em></a><em> website. He was named an ACM Fellow in 2019.</em></p><p><em>This article was originally posted on the </em><a href="https://www.sigarch.org/blog/"><em>SIGPLAN</em></a><em> and </em><a href="https://www.sigarch.org/blog/"><em>SIGARCH</em></a><em> blogs.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a8ef7230bfa7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Guide to Selecting Distinguished Paper Awards]]></title>
            <link>https://emeryberger.medium.com/a-guide-to-selecting-distinguished-paper-awards-7aad56ac9454?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/7aad56ac9454</guid>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[academia]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Tue, 12 Dec 2017 22:11:05 GMT</pubDate>
            <atom:updated>2017-12-12T22:11:05.366Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://emeryberger.com/">Emery Berger</a><br><em>PC chair for PLDI ’16 and SIGPLAN EC Chair for SIGPLAN Research Highlights Awards</em><br>December 2017</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sPYiDG2aF9TrfmlEVhE1Aw.png" /></figure><p><strong>We recommend that all SIGPLAN conferences adopt a formal procedure for selecting ACM SIGPLAN Distinguished Paper Awards </strong>(up to 10% of papers at a conference can be so designated) and recommend doing so via the process of establishing a <strong>Distinguished Paper Committee</strong> to make these decisions.</p><p>Here is how this process works at PLDI, starting with PLDI 2016. This is by no means the only way of setting up such a process, but we found it to be effective.</p><ol><li><strong>Stand up a Distinguished Paper Committee</strong> from the Program Committee, or, if possible, from the External Program Committee (see below regarding EPCs, which have been adopted by PLDI and OOPSLA). The Distinguished Paper Committee should comprise senior, established members of the community. (See <a href="https://pldi16.sigplan.org/committee/pldi-2016-distinguished-paper-committee">https://pldi16.sigplan.org/committee/pldi-2016-distinguished-paper-committee</a> for an example.)</li><li><strong>Request nominations</strong> from the PC (and, if applicable, the EPC) from accepted papers with at least one A (generally all of them) and no D scores (since it’s a bit off to have a distinguished paper with a strong detractor). For PLDI 2016, we had 9 nominations and could select up to 4 (10%). We also recommend that if a paper was deemed to require an artifact, the fact that this artifact was or was not submitted to (and whether or not it passed) the Artifact Evaluation process should be considered as part of the decision-making process.</li><li><strong>Set up a HotCRP instance with the nominated papers, and run like a mini-conference</strong>; meet via conference call. The PC chair should upload only the camera-ready papers to this site, without copying over reviews. Members should not be assigned to review papers they may have reviewed for the conference, since this is an entirely different set of criteria. Reviews should be much shorter (e.g., two paragraphs) and focused on whether they are deserving of distinction. During this period, reviews should be made unavailable on the main conference site; these can be opened up after distinguished paper reviews have been submitted. The timescale can be quite abbreviated: for example, for PLDI 2016, bidding was opened up on April 23, papers assigned on April 26, and May 11th was the deadline for reviews (the conference call was May 13).</li><li><strong>Inform awardees</strong> to ensure that they are in attendance when the awards are presented, typically at the beginning of the conference. In addition, it is possible to have a specific Distinguished Papers session; for double-track conferences, this should be made a single-track so everyone can attend (connecting this session with a keynote makes this logistically straightforward).</li><li><strong>Forward a suitable subset of Distinguished Papers as nominees for SIGPLAN Research Highlights</strong> (recipients of which are forwarded for consideration as CACM Research Highlights). Note that the criteria for CACM Research Highlights are special. <em>Nominated papers should be of broad interest beyond the PL community. They must create excitement. Papers with surprising results that stir stimulating debate are particularly encouraged. The results must be recent, significant, and exciting, and of general interest (and accessible) to the CS research community.</em></li></ol><p>For those unfamiliar with the notion of EPCs, this is from the Chair notes for PLDI 2016.</p><p><em>In addition to the Program Committee, we added an External Program Committee (EPC) consisting of senior members of the PL community who acted as a “light” program committee; their charge was to review roughly ten papers each, and in particular, to review all PC-authored papers. The EPC met via a day-long teleconference prior to the physical PC meeting. A subset of the EPC also formed the Distinguished Papers Committee, whose job it was to select the distinguished papers via a conference-like process.</em></p><p>The EPC is intended to be composed primarily of senior, established researchers (and is complementary to the ERC).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7aad56ac9454" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Guide for Session Chairs]]></title>
            <link>https://emeryberger.medium.com/a-guide-for-session-chairs-8212843c900b?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/8212843c900b</guid>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[public-speaking]]></category>
            <category><![CDATA[academia]]></category>
            <category><![CDATA[conference]]></category>
            <category><![CDATA[research]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Wed, 08 Jun 2016 16:08:14 GMT</pubDate>
            <atom:updated>2016-06-08T16:08:38.243Z</atom:updated>
            <content:encoded><![CDATA[<p>I just sent this message as a guide to the program committee members who will be chairing sessions for <a href="http://conf.researchr.org/home/pldi-2016">PLDI 2016</a> (I figure it’s the first time for some of them). A few people suggested I post it, so here it is (lightly edited, cross-posted from <a href="https://emeryblogger.com/2016/06/08/a-guide-for-session-chairs/">my blog</a>). Additions or other suggestions welcome.</p><ul><li><strong>Find your speakers</strong> before the session begins. You will have to talk to them about some stuff — see below.</li><li>Find out <strong>how to pronounce their names</strong> properly.</li><li>Find out i<strong>f they are on the market next year</strong> — sometimes people like the advertisement that they will be graduating soon.</li><li>Have them <strong>check their equipment</strong> (particularly if they are using Linux…).</li><li>Before each session, <strong>introduce the entire session</strong> (as in, “I am So-and-So, from Wherever University; welcome to the session on drone-based programming languages.”</li><li>Before each talk, <strong>introduce each speaker</strong>. I personally recommend <em>not</em> reading their title, since lots of speakers are on autopilot and will just repeat everything you said. You can instead say something like “This is Foo Bar, who will be talking about verifying clown car drivers.” In fact, come to think of it, you could just say that for every talk.</li><li><strong>Keep track of time</strong>. For PLDI this year, speakers get 25 minutes, and then there are 5 minutes for questions. If you have an iPad, <a href="https://itunes.apple.com/us/app/presentation-clock/id391324914?mt=8">there’s an app I have used</a> to display time to speakers (big giant numbers, you can set it to change colors when you hit 5 min or 1 min till the end). You can of course always go old school and hold up a sheet of paper indicating when time is drawing near. I recommend doing this when there are 5 minutes left and 1 minute left. Let the speakers know you will be doing this.</li><li>When the speaker is done, if it hasn’t happened already,<strong> make sure everyone applauds</strong> by saying “Let’s thank our speaker” and start applauding. Then <strong>open the floor to questions.</strong></li><li><strong>COME PREPARED WITH A QUESTION.</strong> The worst thing ever is when the talk is a disaster does not go well and no one has any questions for the speaker, and then: &lt;crickets&gt;. Read over each paper so you have at least a couple of questions planned. Hopefully it won’t come to this, but it happens sometimes, and it’s great if you can save the day.</li><li>Make sure people who ask questions <strong>use the mic</strong> and state their name and affiliation.</li><li>You may also have to <strong>clarify the question</strong> for the speaker, repeat the question, etc. Understanding questioners can occasionally be a challenge for non-native English speakers: it’s a stressful time, and the questioners may have unfamiliar accents, etc. <strong>Be prepared to give the speaker a helping hand</strong>.</li><li><strong>Be prepared to cut off a questioner</strong>. YOU ARE IN CHARGE OF THE SESSION. If a questioner won’t give up the mic and keeps asking questions and is burning time, rambling, etc., you are empowered to move on to the next questioner (e.g., by suggesting “how about we take this off-line”).</li><li>Hopefully this won’t be an issue you will have to deal with, but <strong>questioners who are belligerent or insulting must not be tolerated</strong>. Cut them off and report them to the program chair (me) or the general chair. I sincerely hope and expect that this will not happen, but I want you to realize you are empowered to take action immediately. You can read over <a href="http://www.sigplan.org/Resources/Policies/CodeOfConduct/">SIGPLAN’s non-harassment policy here</a>, which is based on ACM’s: <a href="http://www.sigplan.org/Resources/Policies/CodeOfConduct/">http://www.sigplan.org/Resources/Policies/CodeOfConduct/</a>.</li><li>To make sure things run smoothly, <strong>have the next speaker on deck</strong> with their laptop a minute or so before question times end. Ideally, they will be setting up while the current speaker is wrapping up questions.</li><li>Finally, when questions are over, say “Let’s thank our speaker again” <strong>and applaud.</strong></li></ul><p>And thanks again to all the session chairs for volunteering!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8212843c900b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Star Trek Case for Double-Blind Reviewing]]></title>
            <link>https://emeryberger.medium.com/the-star-trek-case-for-double-blind-reviewing-540d673a5b0?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/540d673a5b0</guid>
            <category><![CDATA[academia]]></category>
            <category><![CDATA[science]]></category>
            <category><![CDATA[science-fiction]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Wed, 02 Dec 2015 14:35:12 GMT</pubDate>
            <atom:updated>2015-12-03T14:31:03.784Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*TfFv2ixgrAl2p1j8fBd00w.jpeg" /></figure><h4>The planet Vulcan is simultaneously the source of the universe’s worst neck massagers and its best program committee members.</h4><p>Unlike humans, Vulcans are ruthlessly rational and unerringly logical.</p><p>A Vulcan reviewer is unaffected by how often they have mind-melded with the authors of a paper or whether they know them at all, whether the authors have pointed ears or not, or whether (once every seven years), they might be judged to be suitable mates.</p><p>Vulcans are never influenced by the origin and ethnic groups of authors, whether they be Romulan, human, or even Klingon.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/479/1*Q1qJirqmnIrZcXBQqkWiKA.jpeg" /></figure><p>In fact, they have no choice: Vulcans are emotionless and inevitably objective. They are in fact only capable of dispassionately reviewing papers purely on their merits.</p><p>Humans are not Vulcans. But double-blind reviewing lets us act like them — at least when we are reviewing papers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A8f49J9BTGezkMipmHIKFA.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=540d673a5b0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Yes, JavaScript is Assembly for the Web. Here’s its OS.]]></title>
            <link>https://emeryberger.medium.com/yes-javascript-is-assembly-for-the-web-but-where-s-the-os-6ca418592ffa?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/6ca418592ffa</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Fri, 28 Aug 2015 06:13:56 GMT</pubDate>
            <atom:updated>2015-09-01T14:13:18.448Z</atom:updated>
            <content:encoded><![CDATA[<h4>The browser is a lousy excuse for an operating system. So we fixed it.</h4><p><em>by John Vilk and Emery Berger</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7oSWEkEg3KMxNM6qKT6bRg.jpeg" /></figure><h4>Doppio is an “operating system” for the browser that lets it run applications written in general-purpose languages</h4><p>Web browsers have taken over. They make it comparatively easy to deliver cross-platform applications, because browsers are essentially everywhere. Practically all computing platforms — from desktops and tablets to mobile phones — ship with web browsers. Browsers are also getting faster all the time. They have just-in-time compilers for JavaScript that produce highly optimized code, and they expose features like access to the GPU through WebGL and high-speed video chat via WebRTC.</p><p>This combination of features makes it possible for browsers to host the kind of richly interactive applications that used to be restricted to native environments. In effect, web browsers have become a <em>de facto</em> universal computing platform: its operating system is the browser environment, and its sole “instruction set” is JavaScript.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*OJ1rH4eiZMZNQrCWhpfxGw.jpeg" /></figure><h3>JavaScript is Your Frenemy.</h3><p>In short, if you want to program for the web, you need JavaScript. However, JavaScript is not everyone’s favorite language. There are many reasons why browser support for programming languages <em>other than JavaScript </em>would be desirable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*glnsPb-qsZxC23WGGxlk2Q.jpeg" /></figure><p>JavaScript is a language that has some nice features but whose design contains numerous pitfalls for programmers. <a href="https://www.destroyallsoftware.com/talks/wat">Gary Bernhardt’s famous “WAT” talk</a> below hilariously illustrates just a few.</p><p><a href="https://www.destroyallsoftware.com/talks/wat">Wat</a></p><p>For example, here’s what happens when you have to create a new language in <a href="https://www.w3.org/community/webed/wiki/A_Short_History_of_JavaScript"><em>just 10 days</em></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*CL-5o2p1qPcSWNx8Vvuzmw.jpeg" /></figure><p>Problems with JavaScript have led language implementors to design new languages for the browser that overcome JavaScript’s shortcomings — Dart, TypeScript, and <em>many </em>others — but these solutions all require that programmers learn a new language. Programmers who prefer to program in other paradigms (e.g., functional, object-oriented) currently must abandon these or build hacks onto JavaScript to accommodate their needs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DnKDJ681ymhOxyWE0zaBrg.jpeg" /></figure><h3>So. Much. Code.</h3><p>There’s also <em>a lot</em> of well-debugged, existing code already written in general-purpose programming languages (i.e., not JavaScript). Making it possible to reuse this code would speed application development and reduce the risk of introducing new bugs.</p><p>It is already possible to reuse existing C or C++ code via the Emscripten project, which is a backend for LLVM that generates snippets of JavaScript instead of, say, x86 code. An effort is underway to provide <em>really </em>efficient support for JavaScript generated this way (initially ASM.js, now WebAssembly).</p><p><strong>Unfortunately, translating, interpreting, or compiling code written in conventional languages to JavaScript is not enough.</strong> Browsers lack abstractions that existing programming languages expect, and impose significant limitations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/1*1xSAGfZqVWONRNQRE4Mk_Q.jpeg" /></figure><h3><strong>One At A Time.</strong></h3><p>JavaScript is a single-threaded event-driven programming language with no support for interrupts. Events have to execute to completion. If your code happens to have a function that takes too long (for some definition of <em>too long</em>), your script will get killed by the browser’s watchdog thread, triggering the dreaded “page(s) unresponsive message”. This makes programming tricky: since it’s difficult to predict how long your code will take, JavaScript programmers routinely have to break up their code into tiny pieces that yield control back to the main JavaScript event loop.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/295/1*dVyLo9IBiCAPRjGGY42xcw.png" /></figure><h3>Call Me, Maybe<br>(Or Not).</h3><p>Browsers provide web applications with a rich set of functionality, but these APIs are <em>asynchronous</em> — that is, you invoke them with a callback that runs when the function completes. Unfortunately, conventional languages rely on <em>synchronous</em> (blocking) APIs, which don’t need or provide callbacks. Unfortunately, due to the limitations of JavaScript, you can’t directly create synchronous APIs from asynchronous APIs (e.g., by busy-waiting — the browser will just kill your script).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*u0pQA8HGboYVDUnnCrsSjg.jpeg" /></figure><h3>Dude, Where’s My OS?</h3><p>Browsers lack most of the OS services that standard programming languages take for granted. For example, there’s no file system abstraction. Instead, there’s a panoply of limited storage mechanisms, making it tricky to manage large amounts of persistent data. Also missing: sockets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*b-jOseF4uUgFZDznhXVHLQ.png" /></figure><h3>So Many Browsers, So Little Time</h3><p>Another big challenge is the diversity of browsers. Users access the web from a wide range of browser platforms, operating systems, and devices. They also <em>vary widely</em> in their support for and compliance with standards. Each combination may have unique performance characteristics, differing support for JavaScript and Document Object Model (DOM) features, and outright bugs. This diversity makes it hard to address any of the issues above without excluding a large portion of the web audience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*_-Wujv_xMIhVhjBRgidSuA.jpeg" /></figure><h3>Close But No Cigar.</h3><p>Although previous work aims at supporting other languages than JavaScript in the browser, these all fall short. Conventional programming languages and their standard libraries expect the relatively rich execution environment that modern operating systems provide. The fact that browsers lack standard operating systems features like threads, file systems, and blocking I/O means that these projects cannot run existing programs without substantial modifications.</p><h3>Doppio to the Rescue</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*593BQtsbIggLodqC78ldbw.jpeg" /></figure><p>We have built a runtime system called <a href="http://doppiojvm.org"><strong>Doppio</strong></a> that makes it possible to run unmodified applications written in conventional programming languages inside the browser. In short, it’s like a POSIX layer for your browser.</p><p>Doppio’s execution environment overcomes the limitations of the JavaScript single-threaded event-driven runtime model. It provides language implementations with emulated threads that support suspending and resuming execution to enable blocking I/O and multithreading in the source language.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i2kVmWco1A0JMtjq9leBhg.png" /></figure><p>Doppio supplies a wide range of common operating system abstractions that support standard library and language features. These include a Unix-based file system abstraction (providing local and Dropbox-based cloud-based storage), network sockets, and an unmanaged heap for dynamic memory allocation. All of this support acts as an abstraction layer over the many differences between browsers, letting code run unmodified across Google Chrome, Firefox, Safari, Opera, and Internet Explorer. Components of Doppio are already being used by the <a href="https://archive.org/details/softwarelibrary_msdos_games/v2">MS-DOS Collection</a> at the <a href="https://archive.org/">Internet Archive</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/265/1*SaE_c6nfBuCg-hLiu2um8g.png" /></figure><h3>I Heard You Like Java In Your JavaScript</h3><p>To further demonstrate Doppio’s power, we built<strong> </strong><a href="http://doppiojvm.org"><strong>DoppioJVM</strong></a>, a prototype yet robust implementation of a Java Virtual Machine interpreter on top of Doppio. It can run complex unmodified JVM programs in the browser — without that nasty vector for attack, the Java plugin.</p><p>The DoppioJVM is not yet exactly <em>fast</em> — it runs between 24× and 42× slower on CPU-intensive benchmarks in Google Chrome — but it’s already fast enough to be useful. It has already been integrated into an educational website by the University of Illinois (<a href="http://codemoo.com">codemoo.com</a>) that interactively teaches students how to program in Java. We have also enhanced Emscripten with Doppio and found that it made porting a C++ game to the browser far simpler.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*bk7oFIwYwYH_8NRFG6hitA.jpeg" /></figure><p>We are currently expanding on this work on two fronts. The first is an implementation of Python on top of Doppio that we call <a href="https://github.com/plasma-umass/ninia"><strong>Ninia</strong></a> — also known as the coffee snake. Ninia is not yet complete but it is already able to run some basic Python programs in the browser. We are also developing techniques that promise to dramatically speed up both DoppioJVM and Ninia, expanding their usefulness. We look forward to the day when all programmers can run code in the language of their choice directly inside the browser.</p><p><a href="http://jvilk.com/"><em>John Vilk</em></a><em> (PhD student) and </em><a href="http://emeryberger.com"><em>Emery Berger</em></a><em> (Professor) are in the </em><a href="http://plasma.cs.umass.edu"><em>PLASMA</em></a><em> Lab in the College of Information and Computer Sciences at the University of Massachusetts Amherst.</em></p><p><a href="http://people.cs.umass.edu/~emery/pubs/doppio.pdf">A technical paper describing Doppio and the DoppioJVM</a> in detail appeared at <a href="http://conferences.inf.ed.ac.uk/pldi2014/">PLDI 2014</a>, where it won the <a href="http://pldi14-aec.cs.brown.edu/">Distinguished Artifact Award</a>. A video presentation <a href="https://vimeo.com/106106738">is here</a>. The Doppio paper was also selected as a <a href="http://www.sigplan.org/Newsletters/CACM/Papers/">SIGPLAN Research Highlight</a>. Doppio and the DoppioJVM can be downloaded at <a href="https://github.com/plasma-umass/doppio">https://github.com/plasma-umass/doppio</a>; an on-line demo is at <a href="http://doppiojvm.org">doppiojvm.org</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6ca418592ffa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Software Needs Seatbelts and Airbags]]></title>
            <link>https://emeryberger.medium.com/software-needs-seatbelts-and-airbags-6ca62ac11898?source=rss-e3c3ceaf8444------2</link>
            <guid isPermaLink="false">https://medium.com/p/6ca62ac11898</guid>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Emery Berger]]></dc:creator>
            <pubDate>Wed, 19 Aug 2015 04:10:37 GMT</pubDate>
            <atom:updated>2015-08-19T15:21:09.901Z</atom:updated>
            <content:encoded><![CDATA[<h3>SOFTWARE NEEDS SEATBELTS AND AIRBAGS</h3><p><em>Finding and fixing bugs is difficult and time-consuming: there is a better way.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/656/1*Y_WcskQNbrCmFJnVmaqOZQ.jpeg" /></figure><h3>Death, Taxes, and Bugs.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*nBSHhq7U-M7lasRGHYNwLA.gif" /></figure><p>Like death and taxes, buggy code is an unfortunate fact of life. Nearly every program ships with known bugs, and probably all of them end up with bugs that are only discovered post-deployment. Of course, programmers aren’t perfect, but there are many other reasons for this sad state of affairs.</p><h3>Unsafe Languages.</h3><p>One problem is that many applications are written in memory-unsafe languages. Variants of C, including C++ and Objective-C, are especially vulnerable to memory errors like buffer overflows and dangling pointers (<em>use-after-free</em> bugs). These bugs, which can lead to crashes, erroneous execution, and security vulnerabilities, are notoriously challenging to repair.</p><h3>Safe Languages Are No Panacea.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/246/1*u8mHhqSrBSfNXcOSOELN-Q.jpeg" /></figure><p>Writing new applications in memory-safe languages like Java instead of C/C++ would go some way towards mitigating these problems. For example, because Java uses garbage collection, Java programs are not susceptible to use-after-free bugs; similarly, because Java always performs bounds-checking, Java applications cannot suffer memory corruption due to buffer overflows.</p><p>That said, safe languages are no cure-all. Java programs still suffer from buffer overflows and null pointer dereferences, though they throw an exception as soon as they happen, unlike their C-based counterparts. The common recourse to these exceptions is to abort execution and print a stack trace (even to a web page!). Java is also just as vulnerable as any other language to concurrency errors like race conditions and deadlocks.</p><p>There are both practical and technical reasons not to use safe languages. First, it is generally not feasible to rewrite existing code because of the cost and time involved, not to mention the risk of introducing new bugs. Second, languages that rely on garbage collection are not a good fit for programs that need high performance or which make extensive use of available physical memory, since <a href="https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf">garbage collection always requires some extra memory</a>. These include OS-level services, database managers, search engines, and physics-based games.</p><h3>Are Tools the Answer?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/0*Sny9N0ee_fSWbMMn.jpg" /></figure><p>While tools can help, they too cannot catch all bugs. Static analyzers have made enormous strides in recent years, but many bugs remain out of reach. Rather than swamp developers with false positive reports, most modern static analyzers report far fewer bugs than they could. In other words, they trade false negatives (failing to report real bugs) for lower false positive rates. That makes these tools more usable, but also means that they will fail to report real bugs. Dawson Engler and his colleagues made exactly this choice for Coverity’s “unsound” static analyzer (see the Communications of the ACM article on their experiences: <a href="https://www.usenix.org/legacy/event/sec08/tech/slides/engler_slides.pdf"><em>A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World</em></a>.)</p><h3>Testing is Good but Not Enough.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/259/0*PDm7YblmeWUkQDhW.jpg" /></figure><p>The state of the art in testing tools has also advanced dramatically in the last decade. Randomized fuzz testing can be combined with static analysis to drive tests to explore paths that lead to failure. These tools are now in the mainstream: for example, <a href="http://msdn.microsoft.com/en-%20us/library/windows/hardware/gg487310.aspx">Microsoft’s Driver Verifier</a> can test device driver code for a wide variety of problems, and now includes randomized concurrency stress testing.</p><p>But as Dijkstra famously remarked, “Program testing can be used to show the presence of bugs, but never to show their absence!” At some point, testing will fail to turn up new bugs, which will unfortunately be discovered only once the software has shipped.</p><h3>Fixing Bugs: Risky (and Slow) Business.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/0*j90emMB6QKqMebkg.jpg" /></figure><p>Finding the bugs is only the first step. Once a bug is found, whether by inspection, testing, or analysis, fixing it remains a challenge. Any bug fix must be undertaken with extreme care, since any new code runs the risk of introducing yet more bugs. Developers must construct and carefully test a patch to ensure that it fixes the bug without introducing any new ones. This process can be costly and time-consuming. For example, according to Symantec, the average time between the discovery of a remotely exploitable memory error and the release of a patch for enterprise applications is <a href="http://www.symantec.com/enterprise/threatreport/index.jsp">28 days</a>.</p><h3>Cut Bait and Ship.</h3><p>At some point, it simply stops making economic sense to fix certain bugs. Tracking their source is often difficult and time consuming, even when the full memory state and all inputs to the program are available. Obviously, show-stopper bugs must be fixed. For other bugs, the benefits of fixing them may be outweighed by the risks of creating new bugs and the costs in programmer time and in delayed deployment.</p><h3>Debugging at a Distance.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*1uKMz5BMghaDNj_j.jpg" /></figure><p>Once that faulty software has been deployed, the problem of chasing down and repairing bugs becomes exponentially more difficult. Users rarely provide detailed bug reports that allow developers to reproduce the problem.</p><p>For deployed software on desktops or mobile devices, getting enough information to find a bug can be difficult. Sending an entire core file is generally impractical, especially over a mobile connection. Typically, the best one can hope for is some logging messages and a <em>minidump</em> consisting of a stack trace and information about thread contexts.</p><p>Even this limited information can provide valuable clues. If a particular function appears on many stack traces observed during crashes, then that function is a likely culprit. Microsoft Windows <a href="http://www.microsoft.com/about/technicalrecognition/watson-technologies-team.aspx">includes an application debugger</a> (formerly “Watson”, now “Windows Error Reporting”) that is used to perform this sort of triage not only for Microsoft but also for third-party applications via Microsoft’s <a href="http://winqual.microsoft.com/">Winqual program</a>. Google also has made available <a href="http://code.google.com/p/google-breakpad/">a cross-platform tool called Breakpad</a> that can be used to provide similar services for any application.</p><p>However, for many bugs, the kind of information that these tools provide is of limited value. For example, memory corruption errors often trigger failures millions of instructions past the point of the actual error, making stack traces useless. The same is generally true for null dereference exceptions, where the error often happens long after the null pointer was stored.</p><h3>Captain’s Log: Not Enough Information.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/0*gD_1Kh2_zGt8aOwZ.jpg" /></figure><p>On servers, the situation is somewhat improved. Server applications typically generate log messages, which may contain clues to why a program failed. Unfortunately, log files can be unmanageably large. Poring over logs and trying to correlate them to the source code can be extremely time-consuming. Even worse, that work may yield no useful results because the logs are incomplete; that is, the logs simply may not provide enough information to narrow down the source of a particular error because there were not enough or the right kind of log messages. Recent work at Illinois and UC San Diego may lead to tools that address some of these problems; SherLog automates the process of tracing back bugs from log messages to buggy source code paths, and LogEnhancer automatically extends log messages with information to help post-crash debugging. More information on logging appears in a recent Queue article, <a href="https://queue.acm.org/detail.cfm?id=2082137"><em>Advances and Challenges in Log Analysis</em></a>.</p><h3>God Doesn’t Play Dice, but Your Computer Does.</h3><p>Despite these advances, finding bugs has actually become harder than ever. Back when many programs were sequential it was already challenging to find bugs, but now the situation has become far worse. Multithreaded programs, asynchrony, and multiple cores are now a fact of life. Every execution of these non-deterministic programs is completely different from the last because of different timing of events and thread interleavings. This situation makes reproducing bugs impossible even with a complete log of all input events — something that would be too expensive to record in practice anyway.</p><h3>Bumpers, Seatbelts and Airbags.</h3><p>Let’s shift gears for a moment to talk about cars (we’ll get back to talking about software in a minute). As an analogy for the situation we find ourselves in, consider when cars first entered onto the scene. For years, safety was an after-thought at best. When designing new cars, the primary considerations were aesthetics and high performance (think tailfins and V-8 engines).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/0*o5O51psl7JEmi30K.jpg" /></figure><p>Eventually, traffic fatalities led legislators and car manufacturers to take safety into account. Seatbelts became required standard equipment in US cars in the late 1960s, bumpers in the 1970s, and airbags in the 1980s. Modern cars incorporate a wide range of safety features, including laminated windshields, crumple zones, and anti-lock braking systems. It is now practically unthinkable that anyone would ship a car without these essential safety features.</p><p>However, we routinely ship software with no safety measures of any kind. We are in a position similar to that of the automobile industry of the 1950s, delivering software with lots of horsepower and tailfins, complete with decorative spikes on the steering column to make sure that the user will suffer if their application crashes.</p><h3>Drunk-Driving Through a Minefield.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*oxNvU7t2cUzxp9f_.jpg" /></figure><p>The potent cocktail of manual memory management mixed with unchecked memory accesses makes C and C++ applications susceptible to a wide range of memory errors. These errors can cause programs to crash or produce incorrect results. Attackers are also frequently able to exploit these memory errors to gain unauthorized access to systems. Since the vast majority of objects accessed by applications are on the heap, heap-related errors are especially serious.</p><p>Numerous memory errors happen when programs incorrectly free objects. <em>Dangling pointers</em> arise when a heap object is freed while it is still live, leading to use-after-free bugs. <em>Invalid frees</em> happen when a program deallocates an object that was never returned by the allocator by inadvertently freeing a stack object or an address in the middle of a heap object. <em>Double frees</em> are when a heap object is deallocated multiple times without an intervening allocation. This error may at first glance seem innocuous but, in many cases, leads to heap corruption or program termination.</p><p>Other memory errors have to do with the use of allocated objects. When an object is allocated with a size that is not large enough, an <em>out-of-bound error</em> can occur when the memory address to be read or written lies outside the object. Out-of-bound writes are also known as <em>buffer overflows</em>. <em>Uninitialized reads</em> happen when a program reads memory that has never been initialized; in many cases, uninitialized memory contains data from previously-allocated objects.</p><h3>Airbags for Your Applications.</h3><p>Given that we know we will be shipping software with bugs and that the terrain is dangerous, it might make sense to equip it with seat belts and airbags. What we’d like is to have both resilience and prompt corrective action for any problem that surfaces in our deployed applications.</p><p>Let’s focus on C/C++/Objective-C applications — the lion’s share of applications running on servers, desktops, and mobile platforms — and memory errors, the number one headache for applications written in these languages. Safety-equipped memory allocators can play a crucial role in helping to protect your software against crashes.</p><h3>The Garbage Collection Safety Net.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*dMeNmMogpgIu4LZm.jpg" /></figure><p>Dealing with the first class of errors — those that happen because of the misuse of free or delete — can be remedied directly by using garbage collection. Garbage collection works by only reclaiming objects that it allocated, eliminating invalid frees. It only reclaims objects once there is no way to reach those objects anymore by traversing pointers from the “roots”: the globals and the stack. That eliminates dangling pointer errors, since by definition there can’t be any pointers around to reclaimed objects. Since it naturally only reclaims these objects once, a garbage collector also eliminates double frees.</p><p>While C and C++ were not designed with garbage collection in mind, it is possible to plug in a “conservative” garbage collector and entirely prevent free-related errors. The word “conservative” here means that because the garbage collector doesn’t necessarily know what values are pointers (since we are in C-land), it conservatively assumes that if a value looks like a pointer (it is in the right range and properly aligned), and it acts like a pointer (it only points to valid objects), then it may be a pointer.</p><p><a href="http://www.hpl.hp.com/personal/Hans%20Boehm/gc/">The Boehm-Demers-Weiser conservative garbage collector</a> is an excellent choice for this purpose: it is reasonably fast and space-efficient, and can be used to directly replace memory allocators by configuring it to treat calls to free as NOPs.</p><h3>Slipping Through the Net.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*HIpNZ4ZFrtA4zLnH.jpg" /></figure><p>While garbage collectors eliminate free-related errors, they cannot help prevent the second class of memory errors: those that have to do with the misuse of allocated objects such as buffer overflows.</p><p>Runtime systems that can find buffer overflows often impose staggeringly high overheads, making them not particularly suitable for deployed code. Tools like <a href="http://valgrind.org/info/tools.html#memcheck">Valgrind’s MemCheck</a> are incredibly comprehensive and useful, but are heavyweight by design and slow execution by orders of magnitude.</p><p>Compiler-based approaches can reduce overhead substantially by avoiding unnecessary checks, though they entail recompiling all of an application’s code, including libraries. Google has recently made available <a href="http://code.google.com/p/address-sanitizer/wiki/AddressSanitizer">AddressSanitizer</a>, a combination of compiler and runtime technology that can find a number of bugs, including overflows and use-after-free bugs. While it is much faster than Valgrind, its overhead remains relatively high (around 75%), making it primarily useful for testing.</p><h3>Your Program Has Encountered An Error. Goodbye, Cruel World.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/450/0*Czw1PKwTgt3nLhlk.jpg" /></figure><p>All of these approaches are based on the idea that the best thing to do upon encountering an error is to abort immediately. This fail-stop behavior is certainly desirable in testing. However, it is not usually what your users want. Most application programs are not safety-critical systems, and aborting them in midstream can be an unpleasant experience for users.</p><p>Suppose you have been working on a Microsoft Word document for hours (and for some mysterious reason, auto-save has not been turned on). If Microsoft Word suddenly discovers that some error has occurred, what should it do? It could just pop up the window indicating that something terrible has happened and would you like it to send a note home to Redmond. That might be the best thing to do from a debugging perspective, but most people would prefer that Word do its damndest to save the current document rather than fall on its sword if it discovers a possible error. In short, users generally would prefer that their applications be fault tolerant whenever possible.</p><h3>Bohr versus Heisenberg.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/345/0*OGNW2CSDmq969dy8.png" /></figure><p>In fact, the exact behavior users do not want is for an error to happen consistently and repeatably. In his classic 1985 article <em>Why do computers stop and what can be done about it</em>, Jim Gray drew a distinction between two kinds of bugs. The first kind are bugs that behave predictably and repeatably — that is, ones that occur every time that the program encounters the same inputs and goes through the same sequence of steps. These are <em>Bohr bugs</em>, by analogy with the classical atomic model where electrons circle around the nucleus in planetary-like orbits. Bohr bugs are great when debugging a program, since it makes it easier to reproduce the bug and find its root cause.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*6_B7xUjfKMsecFHGdRoqvQ.png" /></figure><p>The second kind of bugs are <em>Heisenbugs</em>, meant to connote the inherit uncertainty in quantum mechanics, which are unpredictable and cannot be reliably reproduced. The most common Heisenbugs these days are concurrency errors, a.k.a. race conditions, which depend on the order and timing of scheduling events to appear. Heisenbugs are also often sensitive to the observer effect; attempts to find the bug by inserting debugging code or running in a debugger often disrupt the sequence of events that led to the bug, making it go away.</p><p>Jim Gray made the point that while Bohr bugs are great for debugging, what users want are Heisenbugs. Why? Because a Bohr bug is a showstopper for the user: every time the user does the same thing, they will encounter the same bug. But with Heisenbugs, the bugs often go away when you run the program again. If a program crashes, and the problem is a Heisenbug, then running the program again is likely to work. This is a perfect match for the way users already behave on the Web. If they go to a web page and it fails to respond, they just click “refresh” and that usually solves the problem.</p><p>So one way we can make life better for users is to convert Bohr bugs into Heisenbugs, if we can figure out how to do that.</p><h3>Defensive Driving with DieHard.</h3><p>My graduate students at the University of Massachusetts Amherst and I, in collaboration with my colleague Ben Zorn at Microsoft Research, have been working for the past few years on ways to protect programs from bugs. The first fruit of that research is a system called <a href="http://diehard-software.org/"><strong>DieHard</strong></a> that makes memory errors less likely to impact users. DieHard eliminates some errors entirely and converts the others into (rare) Heisenbugs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/0*SrU9k27pMGlgq77A.jpg" /></figure><p>To explain how DieHard works, let’s go back to the car analogy. One way to make it less likely for cars to crash into each other is for them to be spaced further apart, providing adequate braking distance in case something goes wrong. DieHard provides this “defensive driving” by taking over all memory management operations and allocating objects in a space larger than required.</p><p>This de facto padding increases the odds that a small overflow will end up in un-allocated space where it can do no harm. However, DieHard doesn’t just add a fixed amount of padding between objects. That would provide great protection against overflows that are small enough, and zero protection against the others. In other words, those overflows would still be Bohr bugs.</p><p>Instead, DieHard provides probabilistic memory safety by randomly allocating objects on the heap. DieHard adaptively sizes its heap be a bit larger than the maximum needed by the application; the default is 1/3. DieHard allocates memory from increasingly large chunks that we call miniheaps.</p><p>By randomly allocating objects across all the miniheaps (see <a href="http://emeryblogger.files.wordpress.com/2012/05/new-heap-diagram.pdf">this diagram for a detailed view</a>), DieHard makes many memory overflows benign, with a probability that naturally declines as the overflow increases in size and as the heap becomes full. The effect is that, in most cases when running with DieHard, a small overflow is likely to have no effect.</p><p>DieHard’s random allocation approach also reduces the likelihood of the free-related errors that garbage collection addresses. DieHard uses bitmaps, stored outside the heap, to track allocated memory. A bit set to ’1’ indicates that a given block is in use, and ’0’ that it is available.</p><p>This use of bitmaps to manage memory eliminates the risk of double frees, since resetting a bit to zero twice is the same as resetting in once. Keeping the heap metadata separate from the data in the heap makes it impossible to inadvertently corrupt the heap itself.</p><p>Most importantly, DieHard drastically reduces the risk of dangling pointer errors, which effectively go away. If the heap has one million freed objects, the chances that you will immediately reuse one that was just freed is literally one in a million. Contrast this with most allocators, which immediately reclaim freed objects. With DieHard, even after 10,000 reallocations, there is still a 99% chance that the dangled object will not be reused.</p><p>Because it performs its allocation in (amortized) constant time, DieHard can provide added safety with very little additional cost in performance. For example, using it in a browser results in no perceivable performance impact.</p><h3>Tolerating Faults FTW with FTH.</h3><p>At Microsoft Research, tests with a variant of DieHard resolved about 30% of all bugs in the Microsoft Office database, while having no perceivable impact on performance. Beginning with Windows 7, Microsoft Windows <a href="http://msdn.microsoft.com/en-us/library/dd744764(v=vs.85).aspx">now ships with a Fault-Tolerant Heap (FTH)</a> that was directly inspired by DieHard. 8 Normally, applications use the default heap, but after a program crashes more than a certain number of times, the Fault-Tolerant Heap takes over. Like DieHard, the Fault-Tolerant Heap manages heap metadata separately from the heap. It also adds padding and delays allocations, though it does not provide DieHard’s probabilistic fault tolerance because it does not randomize allocations or deallocations. The Fault-Tolerant Heap approach is especially attractive because it acts like an airbag: effectively invisible and cost-free when everything is fine, but providing protection when they need it.</p><h3>Exterminating the Bugs.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2zMc4vxcsrfqFr4g.png" /></figure><p>Tolerating bugs is one way to improve the effective quality of deployed software. It would be even better if somehow the software could not only tolerate faults but also correct them. A follow-on to DieHard, called <strong>Exterminator</strong>, does exactly that. Exterminator uses a version of DieHard extended to detect errors, and uses statistical inference to compute what kind of error happened and where the error occurred. Exterminator not only can send this information back to programmers for them to repair the software, but it also automatically corrects the errors via runtime patches. For example, if it detects that a certain object was responsible for a buffer overflow of 8 bytes, it will always allocate such objects (distinguished by their call site and size) with an 8-byte pad. Exterminator can learn from the results of multiple runs or multiple users, so it could be used to proactively push out patches to prevent other users from experiencing errors it has already detected elsewhere.</p><h3>The Future: Safer, Self-Repairing Software.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*scPanhgkx7tSGzJg.jpg" /></figure><p>My group and others (notably Martin Rinard at MIT, Vikram Adve at Illinois, Yuanyuan Zhou at UC-San Diego, Shan Lu at Wisconsin, and Luis Ceze and Dan Grossman at Washington) have made great strides in building safety systems for other classes of errors. We have recently published work on <a href="http://dthreads.org/">systems that prevent concurrency errors</a>, some of which we can eliminate automatically. <strong>Grace</strong> is a runtime system that <a href="https://dl.acm.org/citation.cfm?id=1640096">eliminates concurrency errors for concurrent programs</a> that use “fork-join” parallelism. It hijacks the threads library, converting threads to processes “under the hood”, and uses virtual memory mapping and protection to enforce behavior that gives the illusion of a sequential execution, even on a multicore processor. <strong>Dthreads</strong> (“Deterministic Threads”) is a full replacement for the POSIX threads library that <a href="http://people.cs.umass.edu/~emery/pubs/dthreads-sosp11.pdf">enforces deterministic execution for multithreaded code</a>. In other words, a multithreaded program running with Dthreads never has races; every execution with the same inputs generates the same outputs.</p><p>We look forward to a day in the not too distant future when such safer runtime systems are the norm. Just as we can now barely imagine cars without their myriad of safety features, we are finally adopting a similar philosophy for software. Bugs are inevitable. Let’s deploy safety systems and reduce their impact on users.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6ca62ac11898" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>