High performance with parallel programming

  • Sumo

You know parallel programming is awesome

Why? I am glad you asked, let’s start by looking how Wikipedia defines parallel programming:

Parallel computing is a form of computation in which many calculations are carried out simultaneously, operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently (“in parallel”). There are several different forms of parallel computing: bit-level, instruction level, data, and task parallelism. Parallelism has been employed for many years, mainly in high-performance computing, but interest in it has grown lately due to the physical constraints preventing frequency scaling. As power consumption (and consequently heat generation) by computers has become a concern in recent years, parallel computing has become the dominant paradigm in computer architecture, mainly in the form of multicore processors.

Awesome right? Now let’s make a bit of a clarification:

Multithreaded programming is parallel, but parallel programming is not necessarily multithreaded. Unless the multithreading occurs on a single core, in which case it is only concurrent.

So in other words… if you want to obtain high performance you should definitely consider parallel programming.

Here is a little YouTube video to show its power, I know it is in C#, nothing against C# but as you know we are trying to use Open Source software only so after the video we have some Vala code:

Another good example would be to look at MapReduce.

Here is the code in Vala

class ParallelProgramming {
    private const int MESSAGES = 200000;
    private AsyncQueue<DataBox> thread_queue;
    public ParallelProgramming () {
        this.thread_queue = new AsyncQueue<DataBox> ();
    }
    // data object for sending
    private class DataBox {
        public int number { get; set; }
        public string url { get; set; }
        public DataBox (int number, string url) {
            this.number = number;
            this.url = url;
        }
    }
    private void* writing_func () {
        var timer = new Timer ();
        timer.start ();
        for (int i = 0; i < MESSAGES; i++) {
            var databox = new DataBox (i, @"this is awesome times $i");
            thread_queue.push (databox);
        }
        print ("Added %d Boxes of data into our queue in %f s\n", MESSAGES, timer.elapsed ());
        return null;
    }
    private void* reading_func () {
        var timer = new Timer ();
        timer.start ();
        for (int i = 0; i < MESSAGES; i++) {
            var databox = thread_queue.pop ();
            assert (i == databox.number);
            assert (@"some text for value $i" == databox.name);
            if ((MESSAGES / 2) == databox.number) {
                print ("\tNO: %d \tTEXT: %s\n", databox.number, databox.name);
            }
        }
        print ("Popped %d Boxes of data from our queue in %f s\n", MESSAGES, timer.elapsed ());
        return null;
    }
    public void run () {
        try {
            unowned Thread<void*> first_thread = Thread.create<void*> (writing_func, true);
            unowned Thread<void*> second_thread = Thread.create<void*> (reading_func, true);
            // Wait until the threads finish
            first_thread.join ();
            second_thread.join ();
        } catch (ThreadError e) {
            stderr.printf ("%s\n", e.message);
            return;
        }
    }
}

Why do I care about any of this?

Well remember when we said:

we are going to build a very robust, concurrent and scalable application!

The whole idea is predicated on the fact that we are going to use parallel programming to take advantage of the power of the system in which we are developing.

I want to do this now in PHP

If you want to implement this in PHP then you should consider looking at pcntl_fork so you can create your own Thread class and do something like this:

require_once( 'Threading.php' );
// ensure threading is available
if( !Threading::isAvailable() ) {
    echo 'Cannot continue... threads are not supported';
    exit(0);
}
// function to be ran on separate threads
function do_something( $_limit, $_name ) {
    for ( $index = 0; $index < $_limit; $index++ ) {
        echo 'Now running thread:  ' . $_name . PHP_EOL;
        sleep( 1 );
    }
}
// create 2 thread objects
$t1 = new Thread('do_something'); //callable function is the param in the construct
$t2 = new Thread('do_something');
// start them
$t1->start( 100000, 'do_something_1');
$t2->start( 1000, 'do_something_2');
// keep the program running until the threads finish
while( $t1->isAlive() && $t2->isAlive() ) {
 sleep(1); //don't overload the cpu
}
exit(0);
VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)
High performance with parallel programming, 10.0 out of 10 based on 1 rating

Author: Luis Tineo

Husband, Father, performance improvement junkie, biker and video gamer, Linux user and in my day job I'm a Software Engineer at BuyerQuest.

Share This Post On
  • Joe Watkins

    You could also consider this:

    https://github.com/krakjoe/pthreads

    Actual Threads, and windows support …

    Enjoy

    VA:F [1.9.22_1171]
    Rating: 5.0/5 (1 vote cast)
    VA:F [1.9.22_1171]
    Rating: +1 (from 1 vote)
    • Luis Tineo

      Wow man – thanks for sharing this, pretty awesome. And here I was trying to write my own php extension for multi threading and there was this beauty all along. I really appreciate it.

      VA:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
      VA:F [1.9.22_1171]
      Rating: 0 (from 0 votes)