Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> параллельное программирование, как использовать функцию в WinApi 
:(
    Опции темы
крылья
Дата 24.3.2015, 23:33 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



Привет ребят!! проблема такая, перерыл интернет и не могу разобраться в двух функциях ..
 Я начал заниматься параллельным программированием, и мне нужно явным образом задать процессу определенное ядро в процессоре. К примеру взять два цикла и чтобы они выполнялись на разных ядрах параллельно, или запустить два потока на 2 ядра которые явно укажу..........
 Я знаю что решить эту задачу мне помогут вот эти функции:

 BOOL WINAPI SetProcessAffinityMask(
 _In_ HANDLE hProcess,
 _In_ DWORD_PTR dwProcessAffinityMask
 );

 и еще одна

 BOOL WINAPI GetProcessAffinityMask(
 _In_ HANDLE hProcess,
 _Out_ PDWORD_PTR lpProcessAffinityMask,
 _Out_ PDWORD_PTR lpSystemAffinityMask
 );

 Я не могу разобраться как с ними работать, находятся они в библиотечке "windows.h" (winapi)....всё что знаю о них.

 если кинете простой пример(исходник) с коментами, то буду просто счастлив!!!! 
PM MAIL   Вверх
Wuffur
Дата 25.3.2015, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.7.2007

Репутация: нет
Всего: нет



Вам прямой дорогой сюда товарищ!
SetProcessAffinityMask
GetProcessAffinityMask
Если прогуляться по зависимостям и изучить архитектуру советую скачать Dependancy Walker.
А по Win32 на Рутракторе есть Флёнов, "программирования на С++ глазами Хакера" издательства БХВ-Петербург 2004 года. Она старенькая но отсутствует пугающая перегруженность. 
Буду рад если параллельные Windows программы типа ГИАС выборов(146%) и пресловутая многозадочность с флешки Вашим Трудом наконец оптимизируется! Успешков))

Это сообщение отредактировал(а) Wuffur - 25.3.2015, 08:39
PM MAIL ICQ   Вверх
крылья
Дата 25.3.2015, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



Ну я почитал на офсайте про эти функции, там вроде что-то описания,и для себя извлек не особо много, единственное что узнал если функция завершается ошибкой, возвращаемое значение равно нулю.
Я не понимаю что я получаю от гетера и что делаю в сетере.......
В сетере я прописываю два фактических параметра, первый это "_In_ HANDLE hProcess" что это такое я не понимаю (может это тот поток который будет выполняться на конкретном ядре?), а второй пармаетр "_In_ DWORD_PTR dwProcessAffinityMask" я так понял тут я указываю какой процессор буду использовать (но мне нужно указать ядро).
На одном сайте  увидел такой вот пример где чувак запустил процесс на 15 ядрах

#include <Windows.h>
#include <iostream>

using namespace std;

int main (int argc, char **argv) {
    HANDLE process = GetCurrentProcess(); //мне не ясна вот эта строчка,
    DWORD_PTR processAffinityMask = 1 << atoi(argv[1]); // и тут он вроде как указал ядра процессора

    BOOL success = SetProcessAffinityMask(process, processAffinityMask);

    cout << success << endl;
    return 0;
}

for %c in (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) do test %c

и спасибо вам за помощь

PM MAIL   Вверх
baldina
Дата 25.3.2015, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(крылья @  25.3.2015,  10:41 Найти цитируемый пост)
Я не понимаю что я получаю от гетера и что делаю в сетере.......

Цитата

A thread affinity mask is a bit vector in which each bit represents a logical processor that a thread is allowed to run on. 

что тут непонятно?

Off:
может быть проще будет использовать SetThreadIdealProcessor()?

Добавлено через 8 минут и 50 секунд
Цитата(крылья @  25.3.2015,  10:41 Найти цитируемый пост)
В сетере я прописываю два фактических параметра, первый это "_In_ HANDLE hProcess" что это такое я не понимаю

это handle потока:
Цитата

DWORD_PTR WINAPI SetThreadAffinityMask(
  _In_  HANDLE hThread,
  _In_  DWORD_PTR dwThreadAffinityMask
);

Parameters

hThread [in]
A handle to the thread whose affinity mask is to be set.


Цитата(крылья @  25.3.2015,  10:41 Найти цитируемый пост)
тут я указываю какой процессор буду использовать (но мне нужно указать ядро).

Вы бы поглядели результат GetSystemInfo ()...
PM MAIL   Вверх
крылья
Дата 25.3.2015, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет





то что касается этого -> A thread affinity mask is a bit vector in which each bit represents a logical processor that a thread is allowed to run on. 
я превел текст "Поток сродство маска немного вектор, в котором каждый бит представляет собой логический процессор, который нити разрешено работать на."
исходя из перевода я всё равно не могу понять....

.....я возможно очень тупой, но я пишу на этот форум чтобы вы помогли бы мне объяснить всё это, а в ответ я вижу этот перечень вопросов
1)что тут непонятно?
2)может быть проще будет использовать SetThreadIdealProcessor()?... (можно подумать что я знаю что эта за функция)
3)Вы бы поглядели результат GetSystemInfo ()..(я не знаю что это такое,где она находится функция,для чего она)

Для вас это мелочь, ну не могли бы мне просто кинуть не большой исходник, где запустили бы два цикла на разных ядрах с комментариями подробными....а я бы потом открыл бы в среде этот исходник и посмотрел)
PM MAIL   Вверх
baldina
Дата 26.3.2015, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



вы хотите заменить форумом чтение документации?
это заведомо провальный путь, увы
вы "перерыли интернет", а ответ под боком, из первоисточника, просто вы не в состоянии его понять. документация в основном на английском, и вам придется хотя бы немного поднатореть, т.к. это часть профессии. впрочем, почти весь msdn можно читать по-русски.
имхо вам лучше пока отложить параллельное программирование и заняться программированием вообще и почитать Таненбаума. поймите правильно, это объективная оценка.

по теме:
1. с точки зрения программирования нет "ядер", есть (логические) процессоры. число которых, согласно документации, показывает GetSystemInfo(). здесь есть тонкости типа общего кэша ядер одного физического процессора, но их учет напоминает шаманство (ввиду отсутствия прямолинейных штатных средств), вам это (пока) не нужно 
2. даже из вашего корявого перевода явно, что affinity mask это битовая маска, указывающая на каких процессорах можно выполнять поток. один бит - один процессор
3. SetThreadIdealProcessor позволяет указать не перечень, а единственный номер процессора, на котором должен выполняться поток
4. когда создается процесс, поток и др., они идентифицируются системными указателями типа HANDLE, который возвращает создающая системная функция
5. цель какова? если всего лишь исполнить два фрагмента с использованием двух ядер, для начала просто родите два потока, OS разберется как их исполнить эффективно. есть альтернативы, например директивы OpenMP. В общем случае этого конечно мало, т.к. может потребоваться синхронизация и учет состояния кэшаэ
PM MAIL   Вверх
крылья
Дата 26.3.2015, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



По поводу "родите два потока" мне нужно запустить к примеру два потока Thread на двух ядрах, как мне привести эти потоки к процессу хендела, чтобы в дальнейшем их выполнять на различных ядрах .......в OpenMP нельзя работать с ядрами, только с процессорами, там есть библиотечка для распараллеливания, которая включает 3 алгоритма , но задавать явным способом на выполнение потока конкретным ядром нельзя, там просто машина распаралелеливает на все имеющиеся ядра машины. если у меня 4 то на 4 распаралелит.....но может быть я ошибаюсь
PM MAIL   Вверх
baldina
Дата 26.3.2015, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(крылья @  26.3.2015,  09:18 Найти цитируемый пост)
в OpenMP нельзя работать с ядрами, только с процессорами

да вы и по-русски читаете не очень:
Цитата(baldina @  26.3.2015,  01:03 Найти цитируемый пост)
 с точки зрения программирования нет "ядер", есть (логические) процессоры

т.е. если в системе один процессор QuadCore, то программа увидит четыре процессора, если два DualCore, то тоже четыре. процессор с HT выглядит как несколько логических, хотя основные элементы у него в одном экземпляре.
(число логических процессоров это обычно число физических наборов регистров, контекстов, контроллеров прерываний)

Цитата(крылья @  26.3.2015,  09:18 Найти цитируемый пост)
если у меня 4 то на 4 распаралелит

вообще это дело ОС планировать задачи. маловероятно, что у вас это получится лучше.
цель так и осталась неизвестна, поэтому будем предполагать. два варианта:

1. есть множество задач, которые нужно выполнить (не важно в каком порядке, независимо друг от друга) в параллельных потоках, но не загружая более чем N ядер (логических процессоров). решение - создается пул из N потоков, каждый поток выполняет свою часть задач. начать изучение можно отсюда

2. есть M задач, которые нужно выполнять одновременно (например, они связаны друг с другом), но не более чем на N ядрах (логических процессорах). Тогда создается N потоков, но процессоры, на которых они могут выполняться, ограничиваются при помощи SetProcessAffinityMask() или SetThreadAffinityMask()
кстати, из диспетчера задач windows можно управлять распределением процессоров для конкретного процесса: из контекстного меню процесса выберите "задать соответствие", и увидите в виде галочек те самые биты, которые передаются в SetProcessAffinityMask()

Это сообщение отредактировал(а) baldina - 26.3.2015, 18:28
PM MAIL   Вверх
крылья
Дата 27.3.2015, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



я так понимаю что OpenMP сам распараллеливает на имеющиеся ядра(логические процессоры) программу..............а там я уже не могу задать явное выполнение потоков на конкретных ядрах!??.....
Я вот тут накидал кодик (###код) можете посмотреть и дополнить его чтобы он работал

#include <Windows.h>
 #include <iostream>
 #include <cstdio> 

 using namespace std;

 int main() {

//еще наверно нужно через гетер получить номера свободных или число логических процессоров

 HANDLE process1 = как мне тут указать 2+2;
 HANDLE process2 = и тут 2+2;


 BOOL success1 = SetProcessAffinityMask(process1, 3->0011b);//будет выполняться на первых двух ядрах
 BOOL success2 = SetProcessAffinityMask(process2, 12->1100b);//на последних двух 

 cout << success1 << endl //выведет 1 если всё ок 
 cout << success2 << endl; //
 system("pause");
 return 0;

 }
PM MAIL   Вверх
baldina
Дата 28.3.2015, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



это ерунда а не код. вы напишите работающий код с потоками/процессами, а там поговорим как им процессоры указать.
вы кстати так и не сказали, какая из предложенных схем (или иная) вас интересует.

Добавлено через 6 минут и 36 секунд
Цитата(крылья @  27.3.2015,  23:52 Найти цитируемый пост)
OpenMP сам распараллеливает на имеющиеся ядра(логические процессоры) программу..............а там я уже не могу задать явное выполнение потоков на конкретных ядрах!?

http://en.wikipedia.org/wiki/Affinity_mask
PM MAIL   Вверх
крылья
Дата 28.3.2015, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



Ну  хочу для начала изучить второй  вариант, а потом первый........


 я завтра побольше инфы почитаю и напишу код с вопросами.....спасибо за помощь) 
PM MAIL   Вверх
baldina
Дата 28.3.2015, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



если цель в обучении, вы не с того конца взялись. гляньте в эту книжку, ощутите глубину. в этой книжке кстати ни слова не сказано об управлении процессорами вручную))))

Добавлено через 4 минуты и 57 секунд
вот вам работающий пример
http://coliru.stacked-crooked.com/a/e40b7b4198f25e1d
PM MAIL   Вверх
крылья
Дата 29.3.2015, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



А что делает вот эта строчка "DWORD_PTR mask = (1 << omp_get_thread_num());" строчка??  и что означает эта функция "GetCurrentThread()" я думаю он берет текущий процесс



#include <windows.h>
 #include <omp.h>
 // Set OpenMP thread affinity
 void set_thread_affinity () {
     #pragma omp parallel default(shared)
     {
     DWORD_PTR mask = (1 << omp_get_thread_num());
     SetThreadAffinityMask( GetCurrentThread(), mask );
     }
 }


если я сделаю в этом коде вот так то он распараллелится  на первый два ядра??
#pragma omp paralell for private (j, k) 
 SetThreadAffinityMask( GetCurrentThread(), 3 ); //3 = 0011
for (i=0; i<Size; i++) for (j=0; j<Size; j++) 
for (k=0; k<Size; k++) 
pCMatrix[i*Size+j] += pAMatrix[i*Size+k]*pBMatrix[k*Size+j];
 }

PM MAIL   Вверх
Pavia
Дата 30.3.2015, 06:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: нет
Всего: 12



крылья, 
Цитата(крылья @  29.3.2015,  22:08 Найти цитируемый пост)
А что делает вот эта строчка "DWORD_PTR mask = (1 << omp_get_thread_num());" строчка?? 

RTFM, ответ легко найти в справке.
https://msdn.microsoft.com/ru-ru/library/7w2ke5sx.aspx
https://msdn.microsoft.com/en-us/library/wi...2(v=vs.85).aspx

"<<" оператор сдвига битов влево. 
omp_get_thread_num() - возвращает порядковый номер процесса.

DWORD_PTR mask = (1 << omp_get_thread_num()); - вычисляет маску, где каждому процессу присваивается своё одно ядро.

GetCurrentThread() - не берёт, а получает или возвращает. Функция возвращает хэндел процесса.  
Это особенность виндоуса вместо того чтобы вернуть структуру или указатель на структуру или объект виндоус возвращает хэндел - рычаг. Дергая за этот рычаг можно управлять объектом расположенным в ядре.  
Хэндел - это такой абстрактный указатель. Он может быть чем угодно и указателем и порядковым номером и хэшем и тп. Что однозначно позволяет идентифицировать объект ядра.


PM MAIL   Вверх
крылья
Дата 30.3.2015, 12:48 (ссылка)   | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.3.2015

Репутация: нет
Всего: нет



ну к примеру, я могу в функции main(главная статическая функция)  запустить 1 потока Thread (побочными)........всего у меня будет 2 потока, один главный и один побочный, так вот, к примеру мне нужно чтобы метод побочного потока выполнялся на первом ядре,....приведу пример на С#


 public void ThreadNumbers()
        {
//тут мне нужно сделать так чтобы он выполнялся на первом ядре
//через GetCurrentThread() я возвращаю текущий хэендл (в нашем случае это побочный поток), а единица будет указывать маску для выполнения на первом ядре текущего потока 1-->0001b

 SetThreadAffinityMask( GetCurrentThread(), 1);

            // Информация о потоке
            Console.WriteLine("{0} поток использует метод ThreadNumbers",Thread.CurrentThread.Name);
            // Выводим числа
            for (int i = 0; i < 10; i++)
            {
                Console.Write(i+", ");
                Thread.Sleep(3000);
            }
            Console.WriteLine();
        }

 static void Main()
        {
 
            Thread mythread = Thread.CurrentThread;
            mythread.Name = "Первичный поток";

            //запускаю второй поток который хочу выполнить на первом ядре
             Thread backgroundThread = new Thread(new ThreadStart(mt.ThreadNumbers)); 
      }

Если что-то не правильно подредактируете с коментами, буду очень благодарен
...и еще вопрос такой, в моем случае хэндл это поток я правильно понял ????......но мне не ясно, то что типа этот рычаг управляет объектом в ядре, как это понимать, я же получил поток и по маске даю ему первое ядро на выполнение, что за объект в ядре???..........................извините меня за тупые вопросы, я прост о на жабе пишу, и эта тема для меня нечто новое)))...спасибо за ваш ответ!!
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0571 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.