Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[98.84.18.52] |
|
Сообщ.
#1
,
|
|
|
У процессора 4 ядра - и нужно задействовать все 4. №0 - на все интерфейсные действия пользователя (пока не реализовано), №1 - чтение данных, №2 - самоконтроль данных, №3 - отрисовка графиков.
Пока потоки запускались по очереди - все было нормально. Но когда пытаюсь все ядра задействовать одновременно - 25% процессора делится между этими 3 потоками. Причем работают все 3 ядра - 8% на ядро; то есть, и потоки по ядрам тоже разнесены. Как реализовать так, чтобы эти 3 ядра работали суммарно на 75% от проца, а не на 25%? Если важно - часть исходников по теме. Используется стандартный элемент билдера " File | New | Other | Thread Object". H-файл. //×òåíèå äàííûõ è ðàñïðåäåëåíèå ïî ìàññèâàì. class CThread_1_Core : public TThread { private: protected: void __fastcall Execute(); public: __fastcall CThread_1_Core(bool CreateSuspended); }; //Îòðèñîâêà ãðàôèêà. class CThread_2_Core : public TThread { private: protected: void __fastcall Execute(); public: __fastcall CThread_2_Core(bool CreateSuspended); }; //Åùå ÷òî-íèáóäü. class CThread_3_Core : public TThread { private: protected: void __fastcall Execute(); public: __fastcall CThread_3_Core(bool CreateSuspended); }; CPP-файл. __fastcall CThread_1_Core::CThread_1_Core(bool CreateSuspended) : TThread(CreateSuspended){} __fastcall CThread_2_Core::CThread_2_Core(bool CreateSuspended) : TThread(CreateSuspended){} __fastcall CThread_3_Core::CThread_3_Core(bool CreateSuspended) : TThread(CreateSuspended){} Вызов одним таймером. void __fastcall TForm_Main::Timer_ImportTimer(TObject *Sender) { //Çàãðóçêà äàííûõ. CThread_1_Core *OThread_1_Core = new CThread_1_Core(true); OThread_1_Core->Resume(); //Ïðåäâàðèòåëüíûé ñàìîêîíòðîëü äàííûõ äðóãèì ÿäðîì. if (g_ORocket_Info->iRead_Count != 0) { CThread_3_Core *OThread_3_Core = new CThread_3_Core(true); OThread_3_Core->Resume(); } //Îòðèñîâêà ãðàôèêà äðóãèì ÿäðîì. CThread_2_Core *OThread_2_Core = new CThread_2_Core(true); OThread_2_Core->Resume(); } Один из потоков (по аналогии все остальные). void __fastcall CThread_3_Core::Execute() { SetThreadAffinityMask(GetCurrentThread(), 3 << 1); //Номер ядра, начиная с 0. g_ORocket_Info->vSelfTest(0); Terminate(); Free(); } |
Сообщ.
#2
,
|
|
|
SetThreadAffinityMask() что возвращает?
|
Сообщ.
#3
,
|
|
|
Цитата Mr.Delphist @ Возвращаемые DWORD при первом запуске функции: 1 << 1. 15; 1 << 2. 15; 1 << 3. 15. Если вызывать эту функцию в цикле повторно - числа 8, 2, 4 (в хаотичном порядке и принадлежности потоку). |
Сообщ.
#4
,
|
|
|
Оно так не работает как ты думаешь.
То что поток работает на ядре не значит что он ядро грузит на 100% (особенно GUI). Воткни в функцию каждого потока for(;;); и получишь свои 75% если остальное всё правильно. Вопрос только зачем. |
Сообщ.
#5
,
|
|
|
У меня while (true) стоит во всех потоках. Повторяю: 25% проца делятся между потоками - и эта цифра равна 1 ядру.
|
Сообщ.
#6
,
|
|
|
Цитата Сергей85 @ SetThreadAffinityMask(GetCurrentThread(), 3 << 1); //Номер ядра, начиная с 0. Это что за 3? |
Сообщ.
#7
,
|
|
|
Цитата cppasm @ Делал и 1 << 3 и 3 << 1. Результат один и тот же. |
Сообщ.
#8
,
|
|
|
В итоге, заставил работать только 2 ядра.
#ifndef Functions_ThreadsH #define Functions_ThreadsH #include <Windows.h> //Синхронизация данных разных потоков через использование критических секций. //Ядро №0 - отвечает исключительно за интерфейс как действия пользователя. //Ядро №1. Чтение данных и распределение по массивам. Самоконтроль. Отрисовка графика. //Не удалось использовать несколько ядер одновременно - вся нагрузка идет на ядро №1. class CThread_1_Core : public TThread { private: protected: void __fastcall Execute(); public: __fastcall CThread_1_Core(bool CreateSuspended); }; //Класс для синхронизации доступа к разделяемым данным. class CThread_Synchronize { public: CThread_Synchronize(); //Конструктор. ~CThread_Synchronize(); //Деструктор. void vLock(); //Заблокировать данные. void vUnlock(); //Разблокировать данные. private: //Запрет копирования. CThread_Synchronize(const CThread_Synchronize&); CThread_Synchronize& operator=(const CThread_Synchronize&); CRITICAL_SECTION m_critical_section; //Критическая секция для защиты разделяемых данных. }; #endif Добавлено CThread_Synchronize *g_OThread_Synchronize = new CThread_Synchronize(); //Синхронизация данных потоков, чтобы ядра друг друга не перебивали, и информация не портилась. CThread_1_Core *OThread_1_Core = new CThread_1_Core(false); //Операции с данными (ядро №1). Добавлено void __fastcall TForm_Main::FormClose(TObject *Sender, TCloseAction &Action) { g_bForm_Loaded = false; OThread_1_Core->Suspend(); OThread_1_Core->Terminate(); //OThread_1_Core->Free(); Нельзя, виснет. delete тоже нельзя. |