Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

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

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

07.02.2016, 15:20. Просмотров 188. Ответов 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 потока, а во втором сначала один, а потом другой.

По идее, первый должен выполняться быстрее, но это не так. Первый работает за 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++):

О многопоточности - C++
Интересно, стало, а сколько всего потоков я могу открыть в своем проекте, существуют ли какие нибудь ограничения? и от чего зависит...

изучение многопоточности - C++
с чего стоит начать изучение многопоточности? есть базовые знания по С++, основы ООП. пытался читать Назарр К., Рихтер Дж. - Windows via...

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

Управление потоками в многопоточности - C++
вопрос простой: что посоветуете почитать по теме для начинающего? с помощью чего проще реализовать? windows/linux? (нужно просто...

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

Реализация многопоточности в консоли - C++
Доброго времени суток. Не могу разобраться в многопоточности. Реализовано перемещение по меню с помощью клавиш, и с помощью мыши. Надо...

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

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

Как хранить генератор в каждом из потоков? Решай сам.
1
castaway
Эксперт С++
4920 / 3028 / 372
Регистрация: 10.11.2010
Сообщений: 11,085
Записей в блоге: 10
Завершенные тесты: 1
07.02.2016, 15:51 #5
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
AlexVRud, а где почитать подробнее про это?
Про новый генератор ПСЧ можно почитать тут.
1
AlexVRud
465 / 176 / 46
Регистрация: 04.07.2014
Сообщений: 482
07.02.2016, 16:02 #6
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
C++
1
cout << result
Внутри потоков, то же не есть гуд.
0
DrOffset
7505 / 4501 / 1023
Регистрация: 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
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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