Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
ZaMaZaN4iK
Мой лучший друг-отладчик!
164 / 164 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
Завершенные тесты: 1
#1

Производительность многопоточности - C++

07.02.2016, 15:20. Просмотров 202. Ответов 6
Метки нет (Все метки)

Доброго времени суток. Решил заняться многопоточностью, и натолкнулся на непонимание с производиельность
Есть код в 2 потока:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <thread>
#include <assert.h>
#include <cmath>
#include <ctime>
#include <vector>
 
using namespace std;
 
bool isPrime(long long n)
{
    while(n) n/=10;
    return rand()&1;
}
 
 
void one()
{
    int result = 0;
    for(int  i = 1;i < 50000000; i+=2)
    {
        if(isPrime(i))
            result++;
    }
    cout << result << endl;
}
 
void two()
{
    int result = 0;
    for(int  i = 2;i < 50000000; i+=2)
    {
        if(isPrime(i))result++;
    }
    cout << result << endl;
}
 
 
int main()
{
    thread t1(one);
    thread t2(two);
    t1.join();
    t2.join();
    return 0;
}
Тоже самое, только сингл тред :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <thread>
#include <assert.h>
#include <cmath>
#include <ctime>
#include <vector>
 
using namespace std;
 
bool isPrime(long long n)
{
    while(n) n/=10;
    return rand()&1;
}
 
 
void one()
{
    int result = 0;
    for(int  i = 1;i < 50000000; i+=2)
    {
        if(isPrime(i))
            result++;
    }
    cout << result << endl;
}
 
void two()
{
    int result = 0;
    for(int  i = 2;i < 50000000; i+=2)
    {
        if(isPrime(i))result++;
    }
    cout << result << endl;
}
 
 
int main()
{
    thread t1(one);
    t1.join();
    thread t2(two);
    t2.join();
    return 0;
}
Что делает код : бежит оп порядку по числам, и просто пробегается по цифрам каждого числа и возвращает ересь рандомную. Всё просто и только для теста. Разница в двух исходниках только в одной строчке : в первой у меня работает одновременно 2 потока, а во втором сначала один, а потом другой.
http://www.cyberforum.ru/cpp-beginners/thread1722614.html

По идее, первый должен выполняться быстрее, но это не так. Первый работает за 11 секунд, второй за 1 секунду. Почему так?

Система : Linux Mint 17.3, kernel 4.2, gcc 4.8.4
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2016, 15:20
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Производительность многопоточности (C++):

Синхронизации многопоточности
добрый день, пытаюсь сделать синхронизацию потом на примере producer\consumer,...

изучение многопоточности
с чего стоит начать изучение многопоточности? есть базовые знания по С++,...

Управление потоками в многопоточности
вопрос простой: что посоветуете почитать по теме для начинающего? с помощью...

Подскажите литературу о многопоточности!
Начинал читать QNX/UNIX Анатомия Параллелизма О.Цилюрик Е.Горошко, но там упор...

Реализация многопоточности в консоли
Доброго времени суток. Не могу разобраться в многопоточности. Реализовано...

6
AlexVRud
477 / 189 / 72
Регистрация: 04.07.2014
Сообщений: 527
07.02.2016, 15:34 #2
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
C++
1
return rand()&1;
rand - это блокирующая функция (использует семафор). Поэтому используй другой генератор псевдослучайных чисел.
0
ZaMaZaN4iK
Мой лучший друг-отладчик!
164 / 164 / 30
Регистрация: 24.06.2012
Сообщений: 662
Записей в блоге: 5
Завершенные тесты: 1
07.02.2016, 15:36  [ТС] #3
AlexVRud, а где почитать подробнее про это?
0
AlexVRud
477 / 189 / 72
Регистрация: 04.07.2014
Сообщений: 527
07.02.2016, 15:50 #4
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
а где почитать подробнее про это?
Э-э-э-э, сходу даже не отвечу.

Генератор псевдослучайных чисел, как правило, выдаёт последовательность чисел начиная с определённого состояния. И работает последовательно. Стандартный rand вынужден использовать механизмы синхронизации. Как следствие для каждого потока нужно использовать свой генератор. Для этого можно использовать и random_r, но намного лучше воспользоваться модулем random из С++11.

Как хранить генератор в каждом из потоков? Решай сам.
1
castaway
Эксперт С++
4926 / 3033 / 453
Регистрация: 10.11.2010
Сообщений: 11,089
Записей в блоге: 10
Завершенные тесты: 1
07.02.2016, 15:51 #5
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
AlexVRud, а где почитать подробнее про это?
Про новый генератор ПСЧ можно почитать тут.
1
AlexVRud
477 / 189 / 72
Регистрация: 04.07.2014
Сообщений: 527
07.02.2016, 16:02 #6
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
C++
1
cout << result
Внутри потоков, то же не есть гуд.
0
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
07.02.2016, 16:04 #7
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
первый должен выполняться быстрее, но это не так
Что-то тест у тебя какой-то кривой. Функция rand, если что, непотокобезопасная. Ее использование в таком контексте - UB.
Попробуй так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
bool isPrime(long long n, std::uniform_int_distribution<int> & dist, std::default_random_engine & gen)
{
    while(n) n/=10;
    return dist(gen);
}
 
void one()
{
    std::default_random_engine gen;
    std::uniform_int_distribution<int> dist(0, 1);
 
    int result = 0;
    for(int  i = 1; i < 50000000; i += 2)
    {
        if(isPrime(i, dist, gen))
            result++;
    }
    cout << result << endl;
}
 
void two()
{
    std::default_random_engine gen;
    std::uniform_int_distribution<int> dist(0, 1);
 
    int result = 0;
    for(int  i = 2; i < 50000000; i += 2)
    {
        if(isPrime(i, dist, gen))
            result++;
    }
    cout << result << endl;
}
У меня на двух ядрах получилось 3.643 с в синхронном режиме, против 2.125 с в асинхронном.

Добавлено через 54 секунды
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
а где почитать подробнее про это?
Тут: http://linux.die.net/man/3/rand
The function rand() is not reentrant or thread-safe, since it uses hidden state that is modified on each call. This might just be the seed value to be used by the next call, or it might be something more elaborate. In order to get reproducible behavior in a threaded application, this state must be made explicit;
1
07.02.2016, 16:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.02.2016, 16:04
Привет! Вот еще темы с решениями:

Теория о многопоточности и многопроцессорности
Ребят, возник вот такой вопрос: в каком случае многопоточность и...

Сравнение многопоточности С++11 и WinAPI
У меня скорее теоретический вопрос, чем практический. Есть ли разница работы с...

Объясните принцип создания многопоточности
Здраствуйте, объясните пожалйста как сделать программу многопоточной, у меня...

Реализация многопоточности в GUI приложении
Здравствуйте! Заранее извиняюсь за, возможно, глупые вопросы по поводу этой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru