Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283

Как поддерживать многопоточность?

15.02.2019, 04:14. Показов 2700. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть восьмиядерный процессор, у которого 7 ядер из восьми делают вид, что работают.
А на самом деле нет.

Вот создаём 8 нитей вычислений:
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
    int main(int argc, char *argv[])
    {
        uint32_t n_threads = std::thread::hardware_concurrency();
 
        std::vector<std::thread> threads(n_threads); // создаём массив нитей
        std::vector<uint32_t>    results(n_threads); // сюда каждая нить помещает результат
        std::vector<uint32_t> output;                // сюда мы добавляем понравившиеся результаты
 
        // создаём и запускаем нити
        for (int i = 0; i < n_threads; i++)
        {
            threads[i] = std::thread(&isPrime, candidate, &results[i]);
        }
 
        // ждём завершения работы всех нитей
        for (int i = 0; i < n_threads; i++)
                  threads[i].join();
    
    // смотрим результаты выполнения нитей
    for (int i = 0; i < n_threads; i++)
    {
        if (results[i] > 0) // нить что-то нашла
        {
            output.push_back(results[i]); // добавляем результат в output
        }
    }
Теоретически, всё замечательно. Создали и запустили нити, подождали их завершения и скопировали себе результаты.
Это если нити работают примерно одинаковое время!
А если 7 нитей завершили работу за 1 секунду, а одна из нитей работает 1 час, никакой замечательности нетути!
Пока 8-я нить не завершит работу, 7 ядер процессора простаивают.

Ребятки, есть ли какие-нибудь идеи, чтобы ядра не простаивали?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2019, 04:14
Ответы с готовыми решениями:

Как поддерживать 2 SQL в одном приложении
Приветики! Пишу приложение и хочу что бы оно могло работать как с SQLITE и MySQL в зависимости от выбора пользователя. Есть какой нить...

Как поддерживать постоянную связь локальной БД и БД на сервере?
Речь идет не о локальной сети предприятия. Речь идет об интернете. Мой локальный компьютер - это мой домашний комп, на котором я веду...

Как можно поддерживать высоту одинаковой для каждого из блоков?
Доброго времени суток! В коде ниже три блока, как три колонки: левый, центральный (основной, более широкий), правый. Можно ли прописать...

25
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
15.02.2019, 20:15
Студворк — интернет-сервис помощи студентам
SerVal, позволю себе предположить, что eva2326, имела в виду библиотеку boost.
https://www.boost.org/doc/libs... _pool.html
1
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
15.02.2019, 20:24  [ТС]
Цитата Сообщение от valen10 Посмотреть сообщение
в это время нить[0] может взять на проверку следующее число
Так не может! Назначить задание нити[0] мы можем после того как получим от неё результат.
Для этого надо вызвать для неё thread.join() или future.get(). А это останавливают основную программу.
Другого способа убедиться в завершении нити - нетути.
*проверяется у меня не 8 чисел, а 4-5 миллионов. 8 чисел проверяются параллельно(число ядер процессора).
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
15.02.2019, 20:36
Цитата Сообщение от SerVal Посмотреть сообщение
Назначить задание нити[0] мы можем после того как получим от неё результат
Нить вполне может вести самостоятельное существование: получать задания из одной структуры данных и записывать результат своей работы в другую структуру данных. Впрочем, спорить не намерен, т.к. уже теряю понимание, что в итоге требуется получить. Возможность создания самостоятельных нитей подтвердил кодом выше. Если такой вариант не подходит, давайте признаем его несостоятельным и отложим в сторону.
0
2444 / 1842 / 406
Регистрация: 15.12.2013
Сообщений: 8,243
15.02.2019, 20:57
SerVal, зачем вы вообще напрямую с std::thread работаете? Возьмите библиотеку, где все это сделали за вас. Если используете Visual Studio в которую еще не добавили стандартные алгоритмы, то возьмите PPL от microsoft.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
16.02.2019, 07:52  [ТС]
valen10, вот тут у вас всё и остановится.
В функции main:
C++
1
2
3
4
5
6
size_t primes_count = 0;
 for (size_t i = 0; i < N; ++i) {
 thread_list[i].join();
 cout << "Time " << i << ": " << duration[i] << endl;
 primes_count += result[i].size();
 }
Если одно из заданий выполняется 1 час, Вы будете ждать 1 час(это нормально).
При этом, дать задания освободившимся ядрам Вы не сможете и они будут простаивать.

*впрочем, у меня получается ещё хуже. А может, я ничего не понимаю.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
18.02.2019, 15:41  [ТС]
В общем, распараллелил на 4, 8, 16.. потоков без простоя освободившихся ядер.
Примерно так:
Кликните здесь для просмотра всего текста

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
47
48
49
        std::vector<std::future<void>>  futures(max_threads);
        std::vector<uint32_t>           exponents(max_threads);
        std::vector<uint32_t>           lucas_results(max_threads);
        uint32_t mersen_exp = start_exp;
 
        // создаём и запускаем 4, 8, 16.. потоков
        for (uint32_t thread_num = 0; thread_num < max_threads; thread_num++)
        {
            add_lucas_thread(thread_num, mersen_exp, futures, exponents, lucas_results);
            mersen_exp += 2;
        }
 
        uint32_t futures_size       = futures.size();
        n_exponents_processed       = 0;
        uint32_t next_mersen_exp    = 0;
        int32_t finished_thread_num = -1;
 
        // проверяем завершение потоков. как только один поток завершился, добавляем ещё один. 
        while (n_exponents_processed < exponents_to_go)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50));
 
            finished_thread_num = -1;
            for (uint32_t i = 0; i < futures_size; i++)
            {
                if (futures[i].wait_for(std::chrono::seconds(0)) != std::future_status::ready)
                    continue;
 
                n_exponents_processed++;
 
                if (lucas_results[i])
                {
                    output.push_back(lucas_results[i]);
                }
                finished_thread_num = i;
                break;
            }
 
            if (finished_thread_num < 0) continue; // ни один поток не завершился. 
            
            // поток с finished_thread_num завершился.
            std::cout << "\r Exponents processed : " << n_exponents_processed;
            next_mersen_exp = get_next_mersen_exp(exponents);
        
            if (next_mersen_exp < end_exp) 
                // заменяем завершившейся поток на новый 
                add_lucas_thread(finished_thread_num, next_mersen_exp, futures, exponents, lucas_results);
        
        }

Состояние потоков проверяется каждые 50 миллисекунд.
Всё ускорилось пропорционально числу ядер.
Правда, на компике стало невозможно ничего делать, поскольку все ядра процессора загружены на 100%.
C++
1
2
3
4
5
6
7
8
9
10
11
12
D:\>TestBigInt.exe -getMersenPrimesInRange Mp18 Mp20
 
 Intel(R) Core(TM)2 Quad CPU    Q9650  @ 3.00GHz
 
 Searching in range  : 3217 ... 4423 ( 603 odd exponents )
 Exponents processed : 603
 time : 112.648 sec.
 
 Mersen primes:
 
 Mp18    exponent : 3217
 Mp19    exponent : 4253
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.02.2019, 15:41

Поддерживать нажатое состояние кнопки/клавиши. Как это сделать?
Нужно сделать так, чтобы по нажатию на элемент сработало событие mousedown, а mouseup было проигнорировано! Принцип действия: 1)...

Как всё время поддерживать соединение андроид приложения с веб-сервером?
Подскажите пожалуйста, каким образом можно организовать соединение с веб сервером, что бы в любой момент сервер мог послать данные андроид...

Реализовать программу, задача которой поддерживать значение порта P2 таким же, как и P1
микроконтроллеры 8051 Код: name test main segment code cseg at 0 jmp start rseg main start: mov a,P1 mov P2,P1

Скоро только Windows 10 будет поддерживать новое железо, это как?
Привет всем.Вот постепенно собираю своего монстра.Собираюсь взять либо 6700к либо 5960х в январе прочел новость что мелкие перестанут...

Как узнать максимальный объем одной планки памяти, которую может поддерживать компьютер?
1) Как узнать максимальный объем одной планки памяти, которую может поддерживать компьютер? 2) Это правда, что максимальный...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru