Skip to content
Snippets Groups Projects
Select Git revision
  • 45dc48cfc57ef2dcd653221b8ee48307729e322c
  • master default protected
  • at_palomagr
3 results

programs.js

Blame
  • parallel 4.13 KiB
    //
    // parallel
    //
    // Thrasyvoulos Karydis
    // Neil Gershenfeld
    // (c) Massachusetts Institute of Technology 2016
    //
    // This work may be reproduced, modified, distributed, performed, and
    // displayed for any purpose, but must acknowledge the mods
    // project. Copyright is retained and must be preserved. The work is
    // provided as is; no warranty is provided, and users accept all
    // liability.
    //
    // closure
    //
    (function () {
    //
    // module globals
    //
    var mod = {};
    //
    // name
    //
    var name = 'parallel';
    //
    // initialization
    //
    var init = function () {
        mod.terms.value = '1e8';
        mod.threads.value = '4'
    };
    //
    // inputs
    //
    var inputs = {
        start: {
            type: 'event',
            event: function (evt) {
                benchmark()
            }
        }
    };
    //
    // outputs
    //
    var outputs = {};
    //
    // interface
    //
    var interface = function (div) {
        mod.div = div;
        div.appendChild(document.createTextNode('parallel threads: '));
        var input = document.createElement('input');
        input.type = 'text';
        input.size = 6;
        div.appendChild(input);
        mod.threads = input;
    
        div.appendChild(document.createElement('br'));
        div.appendChild(document.createTextNode('terms to sum: '));
        var input = document.createElement('input');
        input.type = 'text';
        input.size = 6;
        div.appendChild(input);
        mod.terms = input;
    
        div.appendChild(document.createElement('br'));
        var btn = document.createElement('button');
        btn.style.padding = mods.ui.padding;
        btn.style.margin = 1;
        var text = document.createTextNode('calculate pi');
        mod.label = text;
        btn.appendChild(text);
        btn.addEventListener('click', function () {
            benchmark()
        });
        mod.button = btn;
        div.appendChild(btn);
        div.appendChild(document.createElement('br'));
        var text = document.createTextNode('value: ');
        div.appendChild(text);
        mod.value = text;
        div.appendChild(document.createElement('br'));
        var text = document.createTextNode('time (s): ');
        div.appendChild(text);
        mod.time = text;
        div.appendChild(document.createElement('br'));
        var text = document.createTextNode('Mflops: ');
        div.appendChild(text);
        mod.mflops = text;
    
    
    };
    //
    // local functions
    //
    //
    function benchmark() {
        mod.label.nodeValue = 'calculating';
        //
        // Split pi computation by number of workers
        //
        var terms = parseFloat(mod.terms.value);
        var threads = parseFloat(mod.threads.value);
        var inds = [];
        for (var k = 1; k < terms; k += (terms/threads)){
            inds.push(k);}
        inds.push(terms);
        //
        // Spawn workers
        //
        var finished = [];
        var sum_pi = 0;
    
        var st_tm = Date.now();
        for (var i = 0; i < threads; i++) {
            var blob = new Blob(['(' + worker.toString() + '())']);
            var url = window.URL.createObjectURL(blob);
            var webworker = new Worker(url);
            webworker.addEventListener('message', function (evt) {
                var pi = evt.data.pi;
                finished.push('done');
                sum_pi += pi;
                if (finished.length == threads){
                    mod.value.nodeValue = 'value: ' + sum_pi.toFixed(6);
                    var sec = (Date.now()-st_tm)/1000;
                    mod.time.nodeValue = 'time (s): ' + sec;
                    var mflops = 5 * terms / (sec * 1e6);
                    mod.mflops.nodeValue = 'Mflops: ' + mflops.toFixed(0);
                    mod.label.nodeValue = 'calculate pi';
                    sum_pi = 0;
                    finished = [];
                }
                this.terminate()
            });
            webworker.postMessage({start: inds[i],end: inds[i+1]})
        }
        window.URL.revokeObjectURL(url);
    }
    
    //
    
    function worker() {
        self.addEventListener('message', function (evt) {
            var start = evt.data.start;
            var end = evt.data.end;
            var pi = 0;
            var tstart = Date.now();
            for (var term = start; term < end; ++term)
                pi += 0.5 / ((term - 0.75) * (term - 0.25))
            var tend = Date.now();
            var dt = tend - tstart;
            self.postMessage({pi: pi, dt: dt})
        })
    }
    
    //
    // return values
    //
    return ({
       mod:mod,
        name: name,
        init: init,
        inputs: inputs,
        outputs: outputs,
        interface: interface
        })
    
    }());