samedi 20 août 2016

multithreading overhead with mutually independent threads

I'm currently learning about multi-threading features introduced in c++11 and as I was sifting through several SO questions and I found multi-threading brings its own overhead alongside the executing instructions. So I wrote a simple program to compare b/w sequential and multithreaded solution. The conclusion didn't surprised me, sequential was way-way faster than multi-threaded one, probably because it didn't have to deal with creation and management of threads.

But now for another problem, where sequential approach blocks the whole program, multi-threaded one might get an edge -

input.txt

DEVICE#1 4
DEVICE#2 5
DEVICE#3 10
DEVICE#4 1
DEVICE#1 1

prog_seq.cpp

#include <chrono>
#include <fstream>
#include <iostream>
#include <string>
#include <thread>

using string = std::string;
using namespace std::this_thread;  // sleep_for

void executor(string name, int delay)
{
    sleep_for(std::chrono::seconds(delay));
    std::cout << name << std::endl;
}

int main()
{
    string deviceName = "";
    int delay         = 0;

    std::ifstream in("input.txt");

    while (in >> deviceName >> delay) {
        executor(deviceName, delay);
    }

    return 0;
}

Output

DEVICE#1
DEVICE#2
DEVICE#3
DEVICE#4
DEVICE#1

real    0m21.004s
user    0m0.000s
sys 0m0.000s

This program will take atleast 21secs to finish, while the following one will probably finish under 11secs-

prog_thread.cpp

#include <chrono>
#include <fstream>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

using string = std::string;
using namespace std::this_thread;  // sleep_for

void executor(string name, int delay)
{
    sleep_for(std::chrono::seconds(delay));
    std::cout << name << std::endl;
}

int main()
{
    std::vector<std::thread> threadStore;
    string deviceName = "";
    int delay         = 0;

    std::ifstream in("input.txt");

    while (in >> deviceName >> delay) {
        threadStore.emplace_back(std::thread(executor, deviceName, delay));
    }

    for (auto &t : threadStore) {
        t.join();
    }
    return 0;
}

Output

DEVICE#1
DEVICE#4
DEVICE#1
DEVICE#2
DEVICE#3

real    0m10.003s
user    0m0.000s
sys 0m0.000s

So I understand that for such programs, multi-threaded will actually benefit since they'll get completed in shortest order, given they're switched in good manner (if their number grows higher than cores).

Now what I wanted to ask is, for such programs where each thread is executing mutually independent tasks that aren't exactly cpu intensive, but depend more on waiting for inputs or responses from external systems/humans, does the overhead of multi-threading still applies here? Say I have 50 threads all just waiting for input from 50 clients, and since they're not busy doing cpu intensive tasks, would this be a better solution vs some sort of timer in sequential execution(which keeps checking for input after 300msecs again and again).

Also, are there more alternatives to handle such problems, because I would love to know about them.

Aucun commentaire:

Enregistrer un commentaire