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

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

07.02.2016, 15:20. Показов 705. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.02.2016, 15:20
Ответы с готовыми решениями:

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

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

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

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

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

Как хранить генератор в каждом из потоков? Решай сам.
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
07.02.2016, 15:51
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
AlexVRud, а где почитать подробнее про это?
Про новый генератор ПСЧ можно почитать тут.
1
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
07.02.2016, 16:02
Цитата Сообщение от ZaMaZaN4iK Посмотреть сообщение
C++
1
cout << result
Внутри потоков, то же не есть гуд.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
07.02.2016, 16:04
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.02.2016, 16:04
Помогаю со студенческими работами здесь

Часы многопоточности
Помогите пожалуйста. В проект хочу вставить часы, которые будут показывать часы и минуты(соответственно обновляются каждую минуту). Я знаю...

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru