powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Скорость выполнения множества потоков в многоядерном процессоре.
22 сообщений из 22, страница 1 из 1
Скорость выполнения множества потоков в многоядерном процессоре.
    #38784235
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Сейчас МНОГОПОТОЧНАЯ программка выполняется в одноядерной виртуальной машине. Скорость устраивает.
Но хотим выделить нормальную, многоядерную машину(4 или 8), в связи с тем, что там находится и СУБД.
В СУБД пока данных мало, это и пугает.
Visual c++ 2010 XE.
В частности куски программки есть тут .

Вопрос. Следует ли ожидать увеличения скорости выполнения программы?(скорее всего да, но все таки)
И все ли ядра будут использоваться в одном запуске многопоточной программы? (вот тут действительно не понятно)
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38784249
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipok,
скажем так - увеличение скорости работы программы возможно.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38784287
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokВопрос. Следует ли ожидать увеличения скорости выполнения программы?(скорее всего да, но все таки)
Да, если программе не хватает именно процессорного времени. У тебя возможно затык в сети, т.к. все 300 потоков одновременно начинают ее пользовать.
vadipokИ все ли ядра будут использоваться в одном запуске многопоточной программы? (вот тут действительно не понятно)
300 твоих потоков распределятся на все ядра.

Я бы для начала посмотрел как сейчас загружен проц на виртуалке. Если постоянно на 100%, то должно помочь. Если всплесками - то поразбираться

PS Надеюсь ты переписал как я в конце советовал, чтобы объект не создавался каждый раз.

PPS Забыл тогда дописать, я бы еще посоветовал развести пробуждение потоков по времени через какой-то промежуток, например 1 сек., тебе же главное периодичность раз в минуту и не критично если первый IP будет опрашиваться всегда в 00 сек, второй в 01 сек и т.д., тогда и одного процессора в виртуалке может хватить.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785329
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Спасибо!
Dima TДа, если программе не хватает именно процессорного времени. У тебя возможно затык в сети, т.к. все 300 потоков одновременно начинают ее пользовать.

300 твоих потоков распределятся на все ядра.
Потоков уже 500.


Dima TЯ бы для начала посмотрел как сейчас загружен проц на виртуалке. Если постоянно на 100%, то должно помочь. Если всплесками - то поразбираться
C++ программка забивает полностью, потом отпускает, если помните там стоял Sleep(60000); этим и объясняется.


Dima TPS Надеюсь ты переписал как я в конце советовал, чтобы объект не создавался каждый раз.
Переписал, но скорость не устроила.
Может что-то не так делаю?
Код: plaintext
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.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
	while (rs->next())
	{
		t1  = rs->getInt (2);
		t2  = rs->getInt (3);
		t3  = rs->getInt (4);
		t4  = rs->getInt (5);
		ss << t1 << "." << t2 << "." << t3 << "." << t4;
		t = ss.str();

		// параметры запуска потока
		arg_t arg; 
		sprintf_s(arg.ip, sizeof(arg.ip), strdup(t.c_str()));
		//const char babac = (char) rs->getInt (1);
		sprintf_s(arg.employeeID, sizeof(arg.employeeID), "434");
		arg.work = CreateEvent(NULL, false, false, NULL);
		arg.free = CreateEvent(NULL, false, false, NULL);
		HANDLE th = (HANDLE) _beginthreadex(NULL, 0, &getData, (void *) &arg, 0, NULL);
		if(th == NULL) {
			cout << "Error create thread:" << strdup(t.c_str()) << endl;
			CloseHandle(th);
			CloseHandle(arg.work);
			CloseHandle(arg.free);
		} else {
			threads.push_back(th);
			if(WaitForSingleObject(arg.free, 1000) == WAIT_TIMEOUT) { // Ждем инициализацию потока 1000 мс.
				cout << "Error init thread:" << strdup(t.c_str()) << endl;
				CloseHandle(arg.free);
				CloseHandle(arg.work);
			} else {
				th_work.push_back(arg.work);
				th_free.push_back(arg.free);
			}
		}

		//clear
		ss.str(std::string());
		ss.clear();
		t.clear();
	}

	CPU_MEMORY cpu_memory;
	int c;
	// Выполнение полезной работы потоками 
	for(int n = 0; n < 3; n++) { // запускаем все 3 раза
		//Sleep(1000 - GetTickCount() % 1000); // ждем начало секунды
		printf("%d: START\n", GetTickCount());
		for(int i = 0; i < th_work.size(); i++) {
			SetEvent(th_work[i]);
		}
		int res = WaitForMultipleObjects(th_free.size(), &th_free[0], true, INFINITE);
		printf("%d: END\n", GetTickCount());

		for (c=0;c<cpu_memory_vec.size();c++) {
			cpu_memory = cpu_memory_vec[c];
			cout << cpu_memory.employeeID << endl;
			cout << cpu_memory.percentCPU << endl;
			cout << cpu_memory.percentMemory << endl;
			cout << cpu_memory.freeMemory << endl;
		}
		cpu_memory_vec.clear();
	}


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct
{
	char ip[1000];
	char employeeID[1000];
	HANDLE work;
	HANDLE free;
} arg_t;


Это ключевые изменения вашего примера. Если честно, то так и не удалось записать в char employeeID[1000]; значение employeeID.
На время тестов просто записал 434.


Dima TPPS Забыл тогда дописать, я бы еще посоветовал развести пробуждение потоков по времени через какой-то промежуток, например 1 сек., тебе же главное периодичность раз в минуту и не критично если первый IP будет опрашиваться всегда в 00 сек, второй в 01 сек и т.д., тогда и одного процессора в виртуалке может хватить.
Так нельзя сделать, запись в СУБД же происходит. А вектор для INSERT один для всех потоков.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785584
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokDima TPPS Забыл тогда дописать, я бы еще посоветовал развести пробуждение потоков по времени через какой-то промежуток, например 1 сек., тебе же главное периодичность раз в минуту и не критично если первый IP будет опрашиваться всегда в 00 сек, второй в 01 сек и т.д., тогда и одного процессора в виртуалке может хватить.
Так нельзя сделать, запись в СУБД же происходит. А вектор для INSERT один для всех потоков.
Я так понимаю "вектор для INSERT" это хранилище результатов твоих замеров для всех потоков. Узкое место. Что мешает заменить на вектор на очередь и создать отдельный поток для записи в БД? Т.е. потоки пишут свои замеры в очередь, отдельный поток для обмена с БД периодически проверяет что очередь не пуста и если что-то есть, то пишет это в БД.

Если получится избавится от этого вектора, то цикл снаружи можно будет не запускать, перенести ожидание во внутрь потока. Попозже пример сделать постараюсь.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785654
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokДобрый день!
Спасибо!
Dima TДа, если программе не хватает именно процессорного времени. У тебя возможно затык в сети, т.к. все 300 потоков одновременно начинают ее пользовать.

300 твоих потоков распределятся на все ядра.
Потоков уже 500.

А зачем тебе столько, сынок ?
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785780
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Даже не знаю как объяснить.
В начале начальник планировал сканировать за раз 50 машин, я тоже так думал.
Забили, ок, все работает.
Забили больше, опять работает. ))
Дальше больше, и забили всех.

Довольно быстро отрабатывает один круг, поэтому так и оставили.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785795
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipok,

А ты про Thread Pool слышал?
Когда кол-во активных потоков больше количества ядер, то в таком случае имеет место снижение производительности за счёт переключения контекста между потоками на каждом ядре.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785811
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,

В нашем случае не так, доказали методом проб.
Этот закон наверно работает при сложных расчетах.
А у нас тупо извлечение информации по сети.
Причем время отклика информации далеко не одинаково.
Для некоторых машин мгновенно, а некоторые приходится ждать и по 20-30 секунд.
И все это время запущенный процесс не рассчитывает, а тупо ждет.(это уже я так думаю)


vadipokДобрый день!
Сейчас МНОГОПОТОЧНАЯ программка выполняется в одноядерной виртуальной машине. Скорость устраивает.

Обратите на это внимание, я не жалуюсь на скорость.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785887
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изучай
Код: plaintext
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.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <vector>
#include <queue>

#define TIME_STEP  1000 // Шаг повтора, мс
#define TIME_OFFSET 500 // Шаг смещения начала работы, мс

HANDLE stop_thread = NULL;

typedef struct
{
	char ip[20];
	int time_offset;
	HANDLE ready;
} arg_t;

typedef struct
{
	char ip[20];
	int time;
	int cpu;
} result_t;

std::queue<result_t> result;
HANDLE result_change = NULL; // для защиты от изменения result несколькими потоками одновременно

unsigned __stdcall thread( void* pArguments )
{
	// Инициализация потока
	srand(GetTickCount());
	Sleep(rand() % 100); // эмуляция работы
	arg_t arg;
	memcpy(&arg, pArguments, sizeof(arg));
	printf("%d: %s init thread\n", GetTickCount(), arg.ip);
	SetEvent(arg.ready);
	// Выполнение расчетов
	DWORD sleep_time = TIME_STEP - (GetTickCount() + arg.time_offset) % TIME_STEP;
	printf("%d: %s sleep %d ms\n", GetTickCount(), arg.ip, sleep_time);
	while(WaitForSingleObject(stop_thread, sleep_time) != WAIT_OBJECT_0) {
		result_t r; 
		r.time = GetTickCount();
		memcpy(r.ip, arg.ip, sizeof(r.ip));
		// Запрос данных
		printf("%d: %s start\n", GetTickCount(), arg.ip);
		Sleep(rand() % 1000); // эмуляция работы
		r.cpu = rand() % 100;
		// Запись результата в очередь
		WaitForSingleObject(result_change, INFINITE);
		result.push(r);
		SetEvent(result_change);

		sleep_time = TIME_STEP - (GetTickCount() + arg.time_offset) % TIME_STEP;
		printf("%d: %s stop\n", GetTickCount(), arg.ip);
	}
	// Завершение потока
	Sleep(rand() % 100); // эмуляция работы
	printf("%d: %s end thread\n", GetTickCount(), arg.ip);
	_endthreadex(0);
    return 0;
}

int main( void )
{
	stop_thread = CreateEvent(NULL, true, false, NULL);
	result_change = CreateEvent(NULL, false, true, NULL);
	int time_offset = 0;
	// Создание потоков с ожиданием их инициализации
	std::vector<HANDLE> threads;
	for(int i = 0; i < 3; i++)
	{
		arg_t arg; // параметры запуска потока
		sprintf_s(arg.ip, sizeof(arg.ip), "192.168.0.%d", i);
		arg.ready = CreateEvent(NULL, false, false, NULL);
		arg.time_offset = time_offset;
		time_offset = (time_offset + TIME_OFFSET) % TIME_STEP;

		HANDLE th = (HANDLE) _beginthreadex(NULL, 0, &thread, (void *) &arg, 0, NULL);
		if(th == NULL) {
			printf("Error create thread %d\n", i);
			CloseHandle(th);
		} else if(WaitForSingleObject(arg.ready, 1000) == WAIT_TIMEOUT) { // Ждем инициализацию потока 1000 мс.
			printf("Error init thread %d\n", i);
			CloseHandle(th);
		} else {
			threads.push_back(th);
		}
		CloseHandle(arg.ready);
	}
	// Ожидаем результаты и пишем в базу 5 сек.
	DWORD stop_time = GetTickCount() + 5000;
	while(stop_time > GetTickCount()) {
		Sleep(TIME_STEP);
		while(true) {
			WaitForSingleObject(result_change, INFINITE);
			result_t* r = NULL;
			if(!result.empty()) {
				r = &result.front();
			}
			SetEvent(result_change); // чтобы не держать очередь пока идет отправка запроса
			if(r == NULL) {
				break;
			}
			// вставка в базу
			printf("%d: insert into MyTable (IP, time, cpu) values ('%s', %d, %d)\n", GetTickCount(), r->ip, r->time, r->cpu);
			// удаление из очереди
			WaitForSingleObject(result_change, INFINITE);
			result.pop();
			SetEvent(result_change);
		}
	}
	// Завершение работы
	printf("%d: stop all thread\n", GetTickCount());
	SetEvent(stop_thread);
	WaitForMultipleObjects(threads.size(), &threads[0], true, INFINITE);
	CloseHandle(stop_thread);
	CloseHandle(result_change);
	for(int i = 0; i < threads.size(); i++) {
		CloseHandle(threads[i]);
	}
	threads.clear();
	printf("%d: finish\n", GetTickCount());
	system("pause");
}


Заметь что каждый поток повторяет цикл через равный промежуток времени (TIME_STEP). Если минута то TIME_STEP 60000
Для равномерности распределения нагрузки поиграй параметром TIME_OFFSET.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38785997
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokMasterZiv,

Даже не знаю как объяснить.


Если не знаешь, как объяснить, значит, и вообще не знаешь.

Потоков бессмысленно иметь больше, чем кол-во процессоров.

Можно кол-во потоков иметь больше, чем процессоров, на какой-то коэффициент -- коэффициент простоя -- отношение времени, когда задача работает на процессоре ко времени, когда она не в процессоре.

В твоём случае 500 / (скажем, на 8) = 62 потока на процессор, это тогда коэффициент простоя должен быть 1/64 == 1.5 процента.
Это очень мало. Т.е. твои задачи должны быстро заскочить в проц, общитаться, и -- вывалиться ждать чего-то снаружи.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786001
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivПотоков бессмысленно иметь больше, чем кол-во процессоров.
Смысленно :) в его случае, там паузы большие по окончанию цикла обработки, просто не надо их одновременно пробуждать чтоб потоки усиленно боролись за процы.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786057
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TСмысленно :) в его случае, там паузы большие по окончанию цикла обработки, просто не надо их одновременно пробуждать чтоб потоки усиленно боролись за процы.Только в этом случае проще вообще выкинуть многопоточность и запускать потоки в цикле.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786062
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokMasterZiv,

Даже не знаю как объяснить.
В начале начальник планировал сканировать за раз 50 машин, я тоже так думал.
Забили, ок, все работает.
Забили больше, опять работает. ))
Дальше больше, и забили всех.

Довольно быстро отрабатывает один круг, поэтому так и оставили.
Вобщем ничего непонятно. Всё устраивает... но начальник чего-то хочет.
Птичьего молока наверное. Или с ужасом прогнозирует какой-то провал
в перформансе всвязи с ... чем? А фиг его знает с чем.
Кабычегоневышло... Или а вдругспросят...

Ну вобщем дай ему почитать про Заком Амдала .

Дай ему также читануть статью Кнута под названием У создателей комьютеров кончились идеи.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786063
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tпросто не надо их одновременно пробуждать чтоб потоки усиленно боролись за процы
Так это и есть пул потоков :)
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786064
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще данная задача (много одновременных сетевых операций) наиболее правильно решается через пул потоков выполняющих операции асинхронно.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786080
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВобщем ничего непонятно. Всё устраивает... но начальник чего-то хочет.
Птичьего молока наверное. Или с ужасом прогнозирует какой-то провал
в перформансе всвязи с ... чем? А фиг его знает с чем.
Кабычегоневышло... Или а вдругспросят...

Ну вобщем дай ему почитать про Заком Амдала .

Дай ему также читануть статью Кнута под названием У создателей комьютеров кончились идеи.

Стоп, стоп, коллеги!
MasterZiv спросил почему 500, и я ответил. Вы теряете связь.
Этот топиг несет информативный характер для меня. (Вопросы конкретные были в первом сообщении.)
Дальше я просто отвечал людям.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786081
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

А за ссылку спасибо, не знал.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786082
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Изучай
Код: plaintext
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.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <vector>
#include <queue>

#define TIME_STEP  1000 // Шаг повтора, мс
#define TIME_OFFSET 500 // Шаг смещения начала работы, мс

HANDLE stop_thread = NULL;

typedef struct
{
	char ip[20];
	int time_offset;
	HANDLE ready;
} arg_t;

typedef struct
{
	char ip[20];
	int time;
	int cpu;
} result_t;

std::queue<result_t> result;
HANDLE result_change = NULL; // для защиты от изменения result несколькими потоками одновременно

unsigned __stdcall thread( void* pArguments )
{
	// Инициализация потока
	srand(GetTickCount());
	Sleep(rand() % 100); // эмуляция работы
	arg_t arg;
	memcpy(&arg, pArguments, sizeof(arg));
	printf("%d: %s init thread\n", GetTickCount(), arg.ip);
	SetEvent(arg.ready);
	// Выполнение расчетов
	DWORD sleep_time = TIME_STEP - (GetTickCount() + arg.time_offset) % TIME_STEP;
	printf("%d: %s sleep %d ms\n", GetTickCount(), arg.ip, sleep_time);
	while(WaitForSingleObject(stop_thread, sleep_time) != WAIT_OBJECT_0) {
		result_t r; 
		r.time = GetTickCount();
		memcpy(r.ip, arg.ip, sizeof(r.ip));
		// Запрос данных
		printf("%d: %s start\n", GetTickCount(), arg.ip);
		Sleep(rand() % 1000); // эмуляция работы
		r.cpu = rand() % 100;
		// Запись результата в очередь
		WaitForSingleObject(result_change, INFINITE);
		result.push(r);
		SetEvent(result_change);

		sleep_time = TIME_STEP - (GetTickCount() + arg.time_offset) % TIME_STEP;
		printf("%d: %s stop\n", GetTickCount(), arg.ip);
	}
	// Завершение потока
	Sleep(rand() % 100); // эмуляция работы
	printf("%d: %s end thread\n", GetTickCount(), arg.ip);
	_endthreadex(0);
    return 0;
}

int main( void )
{
	stop_thread = CreateEvent(NULL, true, false, NULL);
	result_change = CreateEvent(NULL, false, true, NULL);
	int time_offset = 0;
	// Создание потоков с ожиданием их инициализации
	std::vector<HANDLE> threads;
	for(int i = 0; i < 3; i++)
	{
		arg_t arg; // параметры запуска потока
		sprintf_s(arg.ip, sizeof(arg.ip), "192.168.0.%d", i);
		arg.ready = CreateEvent(NULL, false, false, NULL);
		arg.time_offset = time_offset;
		time_offset = (time_offset + TIME_OFFSET) % TIME_STEP;

		HANDLE th = (HANDLE) _beginthreadex(NULL, 0, &thread, (void *) &arg, 0, NULL);
		if(th == NULL) {
			printf("Error create thread %d\n", i);
			CloseHandle(th);
		} else if(WaitForSingleObject(arg.ready, 1000) == WAIT_TIMEOUT) { // Ждем инициализацию потока 1000 мс.
			printf("Error init thread %d\n", i);
			CloseHandle(th);
		} else {
			threads.push_back(th);
		}
		CloseHandle(arg.ready);
	}
	// Ожидаем результаты и пишем в базу 5 сек.
	DWORD stop_time = GetTickCount() + 5000;
	while(stop_time > GetTickCount()) {
		Sleep(TIME_STEP);
		while(true) {
			WaitForSingleObject(result_change, INFINITE);
			result_t* r = NULL;
			if(!result.empty()) {
				r = &result.front();
			}
			SetEvent(result_change); // чтобы не держать очередь пока идет отправка запроса
			if(r == NULL) {
				break;
			}
			// вставка в базу
			printf("%d: insert into MyTable (IP, time, cpu) values ('%s', %d, %d)\n", GetTickCount(), r->ip, r->time, r->cpu);
			// удаление из очереди
			WaitForSingleObject(result_change, INFINITE);
			result.pop();
			SetEvent(result_change);
		}
	}
	// Завершение работы
	printf("%d: stop all thread\n", GetTickCount());
	SetEvent(stop_thread);
	WaitForMultipleObjects(threads.size(), &threads[0], true, INFINITE);
	CloseHandle(stop_thread);
	CloseHandle(result_change);
	for(int i = 0; i < threads.size(); i++) {
		CloseHandle(threads[i]);
	}
	threads.clear();
	printf("%d: finish\n", GetTickCount());
	system("pause");
}


Заметь что каждый поток повторяет цикл через равный промежуток времени (TIME_STEP). Если минута то TIME_STEP 60000
Для равномерности распределения нагрузки поиграй параметром TIME_OFFSET.

Ок, спасибо большое!
Завтра буду ставить эксперименты на работе.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786087
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovDima TСмысленно :) в его случае, там паузы большие по окончанию цикла обработки, просто не надо их одновременно пробуждать чтоб потоки усиленно боролись за процы.Только в этом случае проще вообще выкинуть многопоточность и запускать потоки в цикле.

Кстати, такие эксперименты я делал.
Скорость получилась лучше, когда запускал все одновременно.
Скорее всего не грамотно делал.
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38786250
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadipokПотоков уже 500.
Еще учти что каждому потоку создается стек 1 Мб, т.е. 0,5 Гб в твоем случае. Смотри чтоб памяти хватало в твоей виртуалке, а то свопится начнет и тормоза возрастут. Своп смотреть в диспетчере задач параметр "Ошибок страниц (изменение)"
...
Рейтинг: 0 / 0
Скорость выполнения множества потоков в многоядерном процессоре.
    #38787491
vadipok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TvadipokПотоков уже 500.
Еще учти что каждому потоку создается стек 1 Мб, т.е. 0,5 Гб в твоем случае. Смотри чтоб памяти хватало в твоей виртуалке, а то свопится начнет и тормоза возрастут. Своп смотреть в диспетчере задач параметр "Ошибок страниц (изменение)"

Добрый день!
В общем все ок, все работает.
Показатели процессора и памяти записываются каждую минуту.
А информация о запущенных процессах записываются 1 раз в 15 шагов.
То есть примерно 1 раз в 15 минут,иначе залью в СУБД излишнюю информацию.
Вот тут были некоторые трудности.
Реализовал вот так:
Код: plaintext
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.
typedef struct
{
	int   step;
	int   flagProcess;
} STEP_PRCESS;

map <int, STEP_PRCESS> step_map;

unsigned __stdcall getData( void* pArguments )
{
...
	//++++++++++++ПРОЦЕССЫ+++++++++++++++++
	STEP_PRCESS step_proc;
	step_proc = step_map[atoi(arg.employeeID)];
	if (step_proc.flagProcess == 1) {

	.....

	} 
	...
	double param, fractpart, intpart;
	param = (double) step_proc.step/ (double) 15;
	fractpart = modf (param , &intpart);
	if (fractpart == 0) {
		step_proc.flagProcess = 1;
	} else {
		step_proc.flagProcess = 0;
	}
	step_proc.step++;
	step_map[atoi(arg.employeeID)] = step_proc;
...
}

int main( void )
{
...
	while (rs->next())
	{
        ...
	STEP_PRCESS step_proc;
	step_proc.flagProcess = 0;
	step_proc.step = 0;
	step_map[rs->getInt (1)] = step_proc; // ключ ID таблицы служащих
        ...
        }
...
}


Не судите строго, все таки я далеко не профи в С++.
Спасибо всем, топик можно закрывать.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Скорость выполнения множества потоков в многоядерном процессоре.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]