Использование потоков ISO C ++ 0x снижает производительность - PullRequest
0 голосов
/ 24 марта 2011

Я пишу программу на C ++, используя потоки для повышения эффективности.

По сути, я просто создаю огромный вектор целых чисел (1 ГБ) и заполняю его случайными числами. Я выполнил программу без потоков и рассчитал необходимое время.

Теперь я хочу использовать 2 потока и увидеть улучшение времени, но программа занимает намного больше времени с 2 потоками, чем без. Не знаю, что я делаю не так: S

#includes...

using namespace std;

//This function just make a for from first to final. Each iteration write a random
//number in the position i of the vector
void generateRandomVector(vector<int> &vec,int first, int final);

//Inside this function i take timestamp2 and calculate the executing time
void calculateTime(clock_t start);


int main(int argc, char *argv[]){

clock_t start;
    double logaritmo;
    int n = 256*1024*1024;


//Taking timestamp 1
start = clock();

    vector<int> vec(n);

    thread t1(generateRandomVector, ref(vec), 0, n/2);
thread t2(generateRandomVector, ref(vec), n/2, n);

t1.join();
t2.join();

calculateTime(start);

Я передаю по ссылке вектор на оба потока, потому что я даю им разные диапазоны, чтобы они никогда не имели доступа к одной и той же позиции.

При необходимости я также могу опубликовать функцию generateRandomVector.

Надеюсь, кто-то может помочь: D

РЕДАКТИРОВАТЬ - generateRandomVector Функция:

void generarRandomVector(vector<int> &vec,int first, int final){
    srand((unsigned)time(0));
    //PID of each thread
    cout << "PID: " << this_thread::get_id() << "\n";

    for(int i = first; i < final; i++){
        vec[i] = static_cast<int> ((double)rand()*(double)(vec.size()) / ((double)RAND_MAX+1.0));
        vec[i] = vec[i] % 10;
    }
}

Ответы [ 3 ]

7 голосов
/ 24 марта 2011

Вот полное решение C ++ 0x с использованием <random> и <chrono>:

#include <random>
#include <chrono>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>

void generarRandomVector(std::vector<int> &vec, int first, int final)
{
    std::mt19937_64 e(time(0));
    std::uniform_int_distribution<> d(0, 9);
    //PID of each thread
    std::cout << "PID: " << std::this_thread::get_id() << "\n";

    for(int i = first; i < final; i++)
        vec[i] = d(e);
}

int main()
{
    typedef std::chrono::high_resolution_clock Clock;
    typedef std::chrono::duration<double> sec;
    int n = 256*1024*1024;
    Clock::time_point start = Clock::now();
    std::vector<int> vec(n);
    std::thread t1(generarRandomVector, std::ref(vec), 0, n/2);
    std::thread t2(generarRandomVector, std::ref(vec), n/2, n);
    t1.join();
    t2.join();
    Clock::time_point end = Clock::now();
    std::cout << sec(end-start).count() << " seconds\n";
}
4 голосов
/ 24 марта 2011

Не используйте rand ().

rand () использует глобальное состояние для генерации следующего числа.Также некоторые источники в сети [1] утверждают, что это «потокобезопасный», что означает, что он может использовать блокировку, тем самым сериализуя все вызовы rand () и устраняя весь параллелизм.1005 *

0 голосов
/ 18 июля 2012

Нет риска состязания данных с приведенным выше кодом, но большой риск получения одинаковых данных в двух половинках вектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...