mercredi 29 avril 2020

Same performance with two threads as with one?

I'm playing around with multithreading to try and get a better understanding of how to implement it in another project and have put together a small example. The code first generates 1000 strings. There is a function foo which loops through each string between two given start and end indexes, checking to see if the character "a" is present (simply for some synthetic load).

When calling foo on the main thread and looping through all 1000 strings, the execution time is ~72ms. When using two separate threads th1 and th2 and passing the foo function pointer along with a start and end index (effectively each thread processes half of the 1000 strings), I was expecting the execution time to be less than ~72ms as it was my understanding that each thread would execute simultaneously, producing an execution time of ~36ms.

However, the execution time is the same as the loop running through all 1000 strings on the main thread. Could someone explain to me why this is the case?

#include <iostream>
#include <vector>
#include <memory>
#include <map>
#include <optional>
#include <string>
#include <algorithm>
#include <chrono>
#include <thread>
#include <iomanip>
#include <cmath>
#include <limits>
#include <ratio>
#include <thread> 

std::chrono::high_resolution_clock::time_point startTime;

std::vector<std::string> strings;

bool string_contains(std::string needle, std::string haystack)
{
    if (haystack.find(needle) != std::string::npos)
    {
        return true;
    }
    return false;
}

std::string random_string(int len)
{
    std::string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    std::string newstr;
    int pos;
    while (newstr.size() != len) {
        pos = ((rand() % (str.size() - 1)));
        newstr += str.substr(pos, 1);
    }
    return newstr;
}

const double now()
{
    std::chrono::duration<double> t = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - startTime);
    return t.count();
}

void build_strings()
{
    for (size_t i = 0; i < 10000; i++)
    {
        strings.push_back(random_string(20));
    }
}

void foo(size_t start, size_t end, size_t thread)
{
    for (size_t i = start; i < end; i++)
    {
        std::cout << thread << "\n";

        if (string_contains("a", strings[i]))
        {

        }
    }
}

int main()
{
    build_strings();

    auto time_a = now();
    std::thread th1(foo, 0, strings.size() / 2, 1);
    std::thread th2(foo, strings.size() / 2, strings.size(), 2);

    //foo(0, strings.size(), 0);

    th1.join();
    th2.join();

    auto time_b = now();

    std::cout << std::setprecision(10) << std::fixed << time_b - time_a << "\n";


    std::cin.get();
}

Aucun commentaire:

Enregistrer un commentaire