v.korleone
Помогающий
Offline
|
|
« : 16-12-2008 13:19 » |
|
Задача: Дана ведомость по результатам здачи экзаменационной сессии. Количество студентов 20. Посчитать средние балы для каждого студента и средний бал по каждой дисциплине. Результаты отобразить на экране. Вопрос: Данная задача сделана, но без розпаралеливания процесов. Помогите розпаралелить процес подсчета средних балов для каждого студента и средний бал по каждой дисциплине. Число процесоров 4.
|
LR.rar (2.63 Кб - загружено 778 раз.)
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #1 : 16-12-2008 13:24 » |
|
Так по потокам распараллеливать, или по процессам? И почему не получается самому?
|
|
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #2 : 16-12-2008 13:36 » |
|
Thread = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); - вот так (это насколько я понял по потокам)
unsigned __stdcall Sum(void * arg) // Функция потока сложения { k+=1; mem[k]=s[i].col+s[i+1].col; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; }; есть вот такой пример, но из-за s .col не хочет компилится
|
|
« Последнее редактирование: 05-01-2009 11:35 от RXL »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #3 : 16-12-2008 13:42 » |
|
что-то я не понял. У тебя что, поток с глобальными данными работает? А не лучше ли, во-первых, наборы данных разделить, а во-вторых, передавать потоку данные через аргумент или иным подобным адекватным образом? А ещё, не вижу у тебя цикла. Ты что именно параллелишь? Какую задачу выполняет 1 поток?
|
|
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #4 : 16-12-2008 13:45 » |
|
Блин, я эти потоки первый раз в жизни вижу У меня есть уже готовая программа, подскажите как с наименшими потерями уже написаного кода розпаралелить программу (желательно с примерами кода)
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #5 : 16-12-2008 13:51 » |
|
Блин, я эти потоки первый раз в жизни вижу
А требование распараллелить из воздуха родилось, что ли? Если уже написанный код написан так, что плохо параллелится - то наименьших потерь не получится. Подумай сам: чтобы был эффект от много поточности, распараллеливать прежде всего нужно независимые вычисления. Какие у тебя вычисления не зависят от результатов друг друга? Какие вычисления можно разделить на "поперечные" части, чтобы потом осталось только собрать воедино результаты этих вычислений? Ответишь на эти вопросы правильно - сформулируешь, как тебе нужно организовать многопоточность.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #6 : 16-12-2008 13:56 » |
|
число процессоров - 4. Те тебе надо не просто в различных тредах запустить, но ещё на мультироцессорной системе? Сам я такое никогда не делал, но там вроде как указатель должен быть для компилятора (pragma?), что этот кусок должен выполнятся на другом проце. Примерчик (точнее статья в журнале), был на вычисление фракталов. Вроде было несложно. Поищи в эту сторону.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #7 : 16-12-2008 14:17 » |
|
Мне нужно розпаралелить процес подсчета средних баллов для каждого студента и средний бал по каждой дисциплине. Аналогия подсчета среднего балла по одной из четырех дисциплин : 1 значение 2 значение 3 значение 4 значение............................... 19 значение 20 значение 1-й ярус ПРОЦЕСОР №1 (1+2)=a ПРОЦЕСОР №2 (3+4)=b ПРОЦЕСОР №3 (5+6)=c ПРОЦЕСОР №4 (7+8)=d 2-й ярус ПРОЦЕСОР №1 (9+10)=e ПРОЦЕСОР №2 (11+12)=f ПРОЦЕСОР №3 (13+14)=g ПРОЦЕСОР №4 (15+16)=h 3-й ярус ПРОЦЕСОР №1 (a+b)=i ПРОЦЕСОР №2 (c+d)=j ПРОЦЕСОР №3 (e+f)=k ПРОЦЕСОР №4 (g+h)=l 4-й ярус ПРОЦЕСОР №1 (i+j)=m ПРОЦЕСОР №2 (k+l)=n ПРОЦЕСОР №3 (17+18)=o ПРОЦЕСОР №4 (g+h)=p 5-й ярус ПРОЦЕСОР №1 (m+n)=r ПРОЦЕСОР №2 (o+p)=s ПРОЦЕСОР №3 -------- ПРОЦЕСОР №4 ---------- 6-й ярус ПРОЦЕСОР №1 (r+s)=t ПРОЦЕСОР №2 ------- ПРОЦЕСОР №3 -------- ПРОЦЕСОР №4 ----------
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #8 : 16-12-2008 14:41 » |
|
v.korleone,
1. В задании которое ты нам показал, нет ни слова про распараллеливание процессов по процессорам. 2. Знания в мультипоточном программировании не так проверяются. 3. Ты скорее всего что то перепутал с распараллеливанием.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #9 : 16-12-2008 15:09 » |
|
McZim вот выложил см.Ответ#8 Мне нужно: 1. Написать ф-ю сумирования типа см.Ответ#3 2. А что-то типа этого должно быть первым ярусом см.Ответ#8: for (i=0;i<3;i++) { //a1=s[i].col; b1=s[i+1].col; Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); } WaitForMultipleObjects(4, Thread, TRUE, INFINITE); cout<<"Потоки окончили выполнение" <<endl; //Закрываем потоки for (i=0;i<4;i++) CloseHandle(Thread[i]); k=0; 3. По анологии сделать остальные ярусы и функции подсчета 4. Из-за использования структур и работы с файлом (рекомендую посмотреть выложеный исходник) проблема с работой этой ф-и: unsigned __stdcall Sum(void * arg) // Функция потока сумирования { k+=1; mem[k]=s[i].col+s[i+1].col; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; };
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #10 : 16-12-2008 15:21 » |
|
v.korleone, какие еще ярусы? Ты хоть понимаешь о чем ты говоришь?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #11 : 16-12-2008 15:30 » |
|
Каждая группа операций наз. ярусом. Пример: см.Ответ#8 Количество ярусов наз. высотой алгоритма и т.д.
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #12 : 16-12-2008 15:31 » |
|
v.korleone, так и причем тут многозадачность?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #13 : 16-12-2008 15:40 » |
|
McZim насчет многозадачности не знаю, прошу помочь разобратся с вот этой байдой: 1. unsigned __stdcall Sum(void * arg) // Функция потока сумирования { k+=1; mem[k]=s[i].col+s[i+1].col; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; }; 2. и с этой: for (i=0;i<3;i++) { //a1=s[i].col; b1=s[i+1].col; Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); } WaitForMultipleObjects(4, Thread, TRUE, INFINITE); cout<<"Потоки окончили выполнение" <<endl; //Закрываем потоки for (i=0;i<4;i++) CloseHandle(Thread[i]); k=0; Мне не нужно лезть в многозадачность, мультипоточность, а просто помочь понять как правильно указать параметры unsigned __stdcall Sum(void * arg) чтобы прога заработала Есть лабораторная работа в которой мы типа розпаралеливаем работу с матрицами. Можете ознакомится, я думаю тогда вы наверняка поймете, что я от вас хочу. P.S. Пишу "типа" т.к. уже понял, что занимались мы в этом семестре херней, а не паралельными вычислениями.
|
|
« Последнее редактирование: 05-01-2009 11:36 от RXL »
|
Записан
|
|
|
|
McZim
|
|
« Ответ #14 : 16-12-2008 16:29 » |
|
v.korleone, ты меня извини, но нет никакого желания, качать твой архив, покажи тут куски кода своей лабы где вы занимаетесь "распаллеливанием", может вы действительно делаете "розпаралеливание", тогда я не знаею что это такое.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #15 : 16-12-2008 16:37 » |
|
#include <windows.h> #include <process.h> #include <iostream> #include <math.h> #include <conio.h> using namespace std;
int a1,b1,i=0,j=0,k=0,K1,K2; unsigned tid; HANDLE Thread[8];// Имитация 8 процесоров DWORD res; int mem[8],a[4],b[4],c[4],d[4],s[4]; //Опис функцій unsigned __stdcall Sum(void * arg) // Функция потока сумирования { k+=1; mem[k]=a1+b1; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; }; unsigned __stdcall Umn(void * arg) // Функция потока умножения { k+=1; mem[k]=a1*b1; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; }; //Тіло програми int main() { SetConsoleOutputCP(1251);
cout<<"Введіть масив A\n"; //Инициализация масива А for (i=0;i<4;i++){ cin>>a[i]; }
cout<<"Введіть масив B\n"; //Инициализация масива В for (i=0;i<4;i++){ cin>>b[i]; }
cout<<"Введіть масив D\n"; //Инициализация масива D for (i=0;i<4;i++){ cin>>d[i]; }
cout<<"\nМасив A: "; //Вывод масива А cout<<endl; for (i=0;i<4;i++){ cout<<a[i]<<"\t"; if (i==1) cout<<endl; } cout<<endl;
cout<<"Масив B: "; //Вывод масива В cout<<endl; for (i=0;i<4;i++){ cout<<b[i]<<"\t"; if (i==1) cout<<endl; } cout<<endl;
cout<<"Масив D: "; //Вывод масива D cout<<endl; for (i=0;i<4;i++){ cout<<d[i]<<"\t"; if (i==1) cout<<endl; } cout<<endl; cout<<"\n"; //Создание потоков_1-й ярус
a1=a[0]; b1=b[0]; Thread[0] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[1]; b1=b[2]; Thread[1] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[2]; b1=b[1]; Thread[2] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[3]; b1=b[3]; Thread[3] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=d[0]; b1=d[3]; Thread[4] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=d[1]; b1=d[2]; Thread[5] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); WaitForMultipleObjects(6, Thread, TRUE, INFINITE ); cout<<"Потоки окончили исполнение" <<endl; //Закрываем потоки for (i=0;i<6;i++) CloseHandle(Thread[i]); k=0;
//Создание потоков_2-й ярус
a1=mem[1]; b1=mem[2]; Thread[0] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); c[0]=mem[1]; a1=mem[3]; b1=mem[4]; Thread[1] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); c[1]=mem[2]; a1=mem[5]; b1=-mem[6]; Thread[2] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); K2=mem[3]; a1=a[0]; b1=b[1]; Thread[3] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[1]; b1=b[3]; Thread[4] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[2]; b1=b[0]; Thread[5] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=a[3]; b1=b[2]; Thread[6] = (HANDLE)_beginthreadex(NULL, 0, Umn, 0, 0, &tid); Sleep(10); a1=d[0]; b1=d[3]; Thread[7] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); WaitForMultipleObjects(8, Thread, TRUE, INFINITE ); cout<<"Потоки окончили исполнение" <<endl; //Закрываем потоки for (i=0;i<8;i++) CloseHandle(Thread[i]); k=0;
//Создание потоков_3-й ярус
a1=mem[4]; b1=mem[5]; Thread[0] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); c[2]=mem[1]; a1=mem[6]; b1=mem[7]; Thread[1] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); c[3]=mem[2]; a1=mem[8]; b1=0; Thread[2] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); K1=mem[3]; a1=a[0]; b1=b[0]; Thread[3] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); s[0]=mem[4]; a1=a[1]; b1=b[1]; Thread[4] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); s[1]=mem[5]; a1=a[2]; b1=b[2]; Thread[5] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); s[2]=mem[6]; a1=a[3]; b1=b[3]; Thread[6] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid); Sleep(10); s[3]=mem[7]; WaitForMultipleObjects(7, Thread, TRUE, INFINITE ); cout<<"Потоки окончили исполнение" <<endl; //Закрываем потоки for (i=0;i<7;i++) CloseHandle(Thread[i]); }
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #16 : 16-12-2008 16:37 » |
|
v.korleone, лекции были? (сомневаюсь, что не было - что за лабы без лекций? у нас, например, в своё время целый семестр хорошего курса ПКТ был) Что было на лекциях?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #17 : 16-12-2008 16:38 » |
|
А не _endthreadex надо, случайно? загоняюсь. С этим всё верно.
|
|
« Последнее редактирование: 16-12-2008 16:40 от Вад »
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #18 : 16-12-2008 16:41 » |
|
Я хочу сделать свою прогу так как там, но из-за использования структур это не удается. Ответ #14 там все написано.
Лекции были, но там все, что в лабе. Программа не хочет работать из-за структур без которых она тоже не будет работать. Как сделать чтобы и с потоками и со структурами?
|
|
« Последнее редактирование: 05-01-2009 11:36 от RXL »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #19 : 16-12-2008 16:55 » |
|
v.korleone, я не понял, "решение" в аттаче - это твоё? А требований, какое должно быть, - нету? Там из задачи нигде не следует того кошмара, который в решении. Offtopic: можно было для москалей и перевести задание, прежде чем выкладывать - а то напрягает, хотя и всё понятно Поставлю в угол. и что там в лабе такого, что было в лекциях?
|
|
« Последнее редактирование: 16-12-2008 16:58 от Вад »
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #20 : 16-12-2008 17:14 » |
|
Вад не совсем понял о каком решении идет речь. Ответ #17 - это уже готовая задача т.е. ЛР сброшеная мной по просьбе McZim. Это просто пример того как мы распаралеливаем задачу, в даном случае работа с матрицами. Это не тот файл, о котором я спрашиваю, это просто пример. По поводу лекций то в них больше болтологии чем реальных примеров (кодов). Хочу получить ответ на просьбы которые были выложены в Ответ #14
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #21 : 16-12-2008 17:21 » |
|
v.korleone, со вторым более-менее всё так, вроде. Поскольку выдрано из контекста - не могу сказать, будет работать или нет, но принцип запуска верный. Что касается лекций и болтологии, то на лекциях и не должно быть примеров в смысле кода. У нас на лекциях были примеры задач и подходы к их распараллеливанию. То, что у тебя в качестве Sum - это что-то невнятное (а скорее всего, к тому же - в корне неверное). Я тебе задал 2 простых вопроса, которые позволят тебе понять, как организовать параллельные вычисления: Какие у тебя вычисления не зависят от результатов друг друга? Какие вычисления можно разделить на "поперечные" части, чтобы потом осталось только собрать воедино результаты этих вычислений? Уточню 2е: если нет независимых вычислений, а есть одна общая большая задача (скажем, просуммировать все элементы огромного одномерного массива данных), то имеет смысл разделить вычисление на куски "поперёк" и выполнять каждую часть в отдельном потоке, чтобы по завершении объединить результаты (скажем, те же отдельные суммы вместе сложить). Вот это вам должны были доводить на лекциях.
|
|
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #22 : 16-12-2008 19:19 » |
|
Вад тебе не кажется, что я это и делаю "если нет независимых вычислений, а есть одна общая большая задача (скажем, просуммировать все элементы огромного одномерного массива данных), то имеет смысл разделить вычисление на куски "поперёк" и выполнять каждую часть в отдельном потоке, чтобы по завершении объединить результаты (скажем, те же отдельные суммы вместе сложить)." посмотри Ответ #8 Дальше твоя цитата "у тебя в качестве Sum - это что-то невнятное (а скорее всего, к тому же - в корне неверное)", значить здесь не внятное, а вот здесь "unsigned __stdcall Sum(void * arg) // Функция потока сумирования { k+=1; mem[k]=a1+b1; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; };" все понятно. Я вас русским языком спрашиваю КАК СДЕЛАТЬ ЧТОБЫ ЭТА ФУНКЦИЯ unsigned __stdcall Sum(void * arg) // Функция потока сумирования { k+=1; mem[k]=s[i].col+s[i+1].col; cout<<"mem["<<k<<"]"<<mem[k]<<endl; return 0; };" РАБОТАЛА ПРИ ИСПОЛЬЗОВАНИИ ЭЛЛЕМЕНТОВ СТРУКТУРЫ??? Я хочу сделать аналогию программы см.Ответ #17, но НЕ РАБОТАЕТ потому что переменные, которые используются в функции есть эллементы структуры. КАК СДЕЛАТЬ? Без многоговорящих отмазок типа "многозадачность", "мультипоточность" "а вам на лекциях должны читать" "а вот на лекциях у нас" и т.д. Можете подсказать, напишите, не можете не надо. Помоему все, что можна было описать по поводу программы я сказал и показал.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #23 : 16-12-2008 19:23 » |
|
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #24 : 16-12-2008 19:25 » |
|
Не нервничай. Посчитать средние балы для каждого студента и средний бал по каждой дисциплине. Результаты отобразить на экране. - это у тебя написано? Посчитать средний балл для каждого студента - это независимые друг от друга вычисления? Посчитать средний балл по каждой дисциплине - это независимые друг от друга вычисления? Ну и ещё: что делает твой поток Sum: выводит сумму двух чисел на экран? Зачем? Что ты при этом параллелишь? Элементы какой структуры ты собираешься использовать? Почему в качестве глобальных параметров? Потоки поддерживают передачу аргументов в функцию потока - см. мануал и примеры для _beginthreadex Покажи не многопоточное решение, обычное, не параллельное. По крайней мере, сделай для себя и посмотри, как можно разделить задачу на параллельные части.
|
|
« Последнее редактирование: 16-12-2008 19:27 от Вад »
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #25 : 16-12-2008 19:33 » |
|
Вад посмотри Ответ #8 (первый проц считает 1+2 значение, второй 3+4 и т.д.) Алексей1153++ Спасибо за ссылку
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #26 : 16-12-2008 19:37 » |
|
v.korleone, ты знаешь, что такое накладные расходы на многопоточность? Представляешь себе, если на каждый чих новый поток заводить? Тебе сказано распараллелить вычисления, а не распылить 4х потоков достаточно. И рискну предположить, что преподаватель именно 4 потока и хочет увидеть - ну, максимум, 8.
|
|
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #27 : 16-12-2008 19:41 » |
|
"Ну и ещё: что делает твой поток Sum: выводит сумму двух чисел на экран? Зачем? Что ты при этом параллелишь?" - я делаю так как в ЛР которую я выложил. Элементы какой структуры ты собираешься использовать? - я выложил исходник файла, зачем же на пальцах все объяснять если можно все наглядно посмотреть. Хотите на пальцах ладно: структура студент, s .col - количество балов для i-того студента.
Почему в качестве глобальных параметров? - потому что работаю с файлом (если я правильно понял вопрос). Здесь расмотрю ваши предложения. Тебе сказано распараллелить вычисления, а не распылить 4х потоков достаточно. И рискну предположить, что преподаватель именно 4 потока и хочет увидеть - ну, максимум, 8. - может быть, твои предложения?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #28 : 16-12-2008 19:45 » |
|
Мои предложения (как сделал бы - да впрочем, как примерно и делал я, когда был студентом): 1 часть. 4 потока, каждый поток считает средние оценки для 1/4 всех студентов 2 часть. 4 потока, каждый поток считает среднее для одной дисциплины.
По-моему, это очевидное разделение задачи на 4 процессора для ускорения вычислений.
|
|
|
Записан
|
|
|
|
v.korleone
Помогающий
Offline
|
|
« Ответ #29 : 16-12-2008 19:50 » |
|
ты хотел сказать для 1/5 т.к. студентов 20?
|
|
|
Записан
|
|
|
|
|