powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Потоковый сервер на С++
94 сообщений из 94, показаны все 4 страниц
Потоковый сервер на С++
    #38208109
kiruhin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Стала задача написать сервер на плюсах (под линукс). Признаться, данный язык только начал осваивать, поэтому могу показаться совсем уж нубом (за что прошу больно не пинать :) ). Итак, задача:
1. Реализация потокового (pre-thread) сервера на С++ под Linux (GNU)
2. В данном случае не оговариваются действия сервера (его логика - это сам осилю), а только грамотное построение модели (принял - передал)
3. Подчеркиваю - код для Linux
Начал с того, что гуглил много. В итоге нашел некий "пример" (код ниже), который взял за основу, которую в последствии буду "допиливать". Итак, код был взят отсюда:
http://www.unix.com/programming/17611-multi-threaded-server-pthreads-sleep.html
Дублирую код в топик:
Код: 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.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
#include <pthread.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>

#define MAX_CLIENT_PER_THREAD 300
#define MAX_THREAD 200
#define PORT 3355
#define MAX_CLIENT_BUFFER 256
/*#define DEBUG*/

int listenfd;

typedef struct {
	pthread_t tid;
	int client_count;
	int clients[MAX_CLIENT_PER_THREAD];
} Thread;

pthread_cond_t new_connection_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t new_connection_mutex = PTHREAD_MUTEX_INITIALIZER;


Thread threads[MAX_THREAD];

void nonblock(int sockfd)
{
	int opts;
	opts = fcntl(sockfd, F_GETFL);
	if(opts < 0)
	{
		perror("fcntl(F_GETFL)\n");
		exit(1);
	}
	opts = (opts | O_NONBLOCK);
	if(fcntl(sockfd, F_SETFL, opts) < 0) 
	{
		perror("fcntl(F_SETFL)\n");
		exit(1);
	}
}

void *thread_init_func(void *arg)
{
	int tid = (int) arg;
	
	int readsocks;
	int i;
	char buffer[MAX_CLIENT_BUFFER];
	char c;
	int n;
#ifdef DEBUG
	printf("thread %d created\n", tid);
	printf("sizeof thread.clients: %d\n", sizeof(threads[tid].clients));
#endif
	memset((int *) &threads[tid].clients, 0, sizeof(threads[tid].clients));
	memset((char *) &buffer, 0, sizeof(buffer));	
	while(1)
	{
#ifdef DEBUG
		printf("thread %d running, client count: %d\n", tid, threads[tid].client_count);
		sleep(3);
#endif
		sleep(1); /* <-- it works ??? :-| */

		for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
		{
			if(threads[tid].clients[i] != 0)
			{
				n = recv(threads[tid].clients[i], buffer, MAX_CLIENT_BUFFER, 0);
				if(n == 0)
				{
#ifdef DEBUG
					printf("client %d closed connection 0\n", threads[tid].clients[i]);
#endif
					threads[tid].clients[i] = 0;
					threads[tid].client_count--;
					memset((char *) &buffer, 0, strlen(buffer));
				}
				else if(n < 0)
				{
					if(errno == EAGAIN)
					{
#ifdef DEBUG
						printf("errno: EAGAIN\n");
#endif
					}
					else {
#ifdef DEBUG
						printf("errno: %d\n", errno);
#endif
						threads[tid].clients[i] = 0;
						threads[tid].client_count--;
						memset( (char *) &buffer, 0, strlen(buffer));
#ifdef DEBUG
						printf("client %d closed connection -1\n", threads[tid].clients[i]);
#endif
					}
				}
				else {
#ifdef DEBUG
					printf("%d bytes received from %d - %s\n", n, threads[tid].clients[i], buffer);
#endif
					
					send(threads[tid].clients[i], buffer, strlen(buffer), 0);
					memset((char *) &buffer, 0, strlen(buffer));
				}
			}
		}
	}
}

int choose_thread()
{
	int i=MAX_THREAD-1;
	int min = 0;
	while(i > -1)
	{
		if(threads[i].client_count < threads[i-1].client_count)
		{
			min = i;
			break;
		}
		i--;
	}		
	return min;
}

int main()
{
	char c;
	struct sockaddr_in srv, cli;
	int clifd;
	int tid;
	int i;
	int choosen;

	signal(SIGPIPE, SIG_IGN);
	
	if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("sockfd\n");
		exit(1);
	}
	bzero(&srv, sizeof(srv));
	srv.sin_family = AF_INET;
	srv.sin_addr.s_addr = INADDR_ANY;
	srv.sin_port = htons(PORT);

	if( bind(listenfd, (struct sockaddr *) &srv, sizeof(srv)) < 0)
	{
		perror("bind\n");
		exit(1);
	}
	
	listen(listenfd, 1024);

	
	/* create threads  */
	for(i = 0; i < MAX_THREAD; i++)
	{
		pthread_create(&threads[i].tid, NULL, &thread_init_func, (void *) i);
		threads[i].client_count = 0;
	}
	

	for( ; ; )
	{
		clifd = accept(listenfd, NULL, NULL);
		nonblock(clifd);

		pthread_mutex_lock(&new_connection_mutex);
		
		choosen = choose_thread();

		for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
		{
			if(threads[choosen].clients[i] == 0)
			{
#ifdef DEBUG
				printf("before threads clifd\n");
#endif
				threads[choosen].clients[i] = clifd;
#ifdef DEBUG
				printf("after threads clifd\n");
#endif
				threads[choosen].client_count++;
				break;
			}
		}

#ifdef DEBUG
		printf("choosen: %d\n", choosen);

		for(i = 0; i < MAX_THREAD; i++)
		{
			printf("threads[%d].client_count:%d\n", i, threads[i].client_count);
		}
#endif

		pthread_mutex_unlock(&new_connection_mutex);
	}

	if(errno)
	{
		printf("errno: %d", errno);
	}
	
	return 0;
}


Сам автор этого кода, в своем посте пишет:
"I am trying to writa a multi-client & multi-threaded TCP server.
There is a thread pool. Each thread in the pool will handle
requests of multiple clients.

But here I have a problem. I find a solution but it is not how
it must be... i think. When threads working without sleep(1)
I can't get response from server but when I put sleep(1) in
thread function as you will see in code, everything works fine
and server can make echo nearly for 40000 clients between
1 or 2 seconds. What am I doing wrong here?
"
И это действительно так. С одной оговоркой, что если заккоментировать sleep(1), то это сервер работает именно так, как нужно, НО вводит систему в ступор (загрузка ЦП 100%, что очевидно, т.к. while(1) ) С другой стороны, из-за этого sleep(1), во-первых, ответ сервера возвращается только через секунду, во-вторых, если передать серверу несколько пакетов (передать быстро), то он "склеит" это пакеты в один, как следствие, пакеты невозможно будет разобрать.
Пожалуйста, подскажите:
1. Если приведенный пример (код, взятый за основу) корректный - как можно избежать sleep (1)?
2. Если код в своей основе неверный (или морально устарел, т.к. пост датируется аж 2005 годом) - помогите собрать этот покотовый сервер (хоть пример реально работающего)
3. Обязательно ли объявлять сокет неблокируемым (как в приведенном примере)?
Спасибо огромное!
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208113
Фотография vromanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kiruhin,

Посмотрите в сторону, напримре, libev
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208182
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kiruhin,

Ну вот у вас бесконечный цикл, в котором при отсутствии данных от клиентов процессор занят на 100%, но ничего полезного не делает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
while(1)
{
	for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
	{
 	    	n = recv(threads[tid].clients[i], buffer, MAX_CLIENT_BUFFER, 0);
 	    	...
	}
	...
}



Используйте функцию select() для выбора сокетов по которым прибыли данные.
Это если просто шоб работало хоть как-то.
А если правильно делать, с нормальной производительностью при большом числе клиентов, то выше посоветовали библиотеку которая реализует все как надо. Там доках наверняка готовые примеры есть. Таких библиотек несколько.

ЗЫ. А вообще, это конечно никакой не С++, а голый С. Для С++ есть библиотека Boost.Asio где все что надо есть, включая пул потоков.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208183
Anatoly MoskovskyЗЫ. А вообще, это конечно никакой не С++, а голый С. Для С++ есть библиотека Boost.Asio где все что надо есть, включая пул потоков.
А он как по производительности относительно libev/libevent, не уступает им?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208186
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
относительно libev libeventДля С++ есть библиотека Boost.Asio где все что надо есть, включая пул потоков.
А он как по производительности относительно libev/libevent, не уступает им?
Архитектурно - не уступает.
А абсолютную скорость не мерял. Но думаю что такая же, т.к. и то и то - легковесные обертки непосредственно над АПИ ОСи
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208188
Anatoly Moskovskyотносительно libev libeventпропущено...

А он как по производительности относительно libev/libevent, не уступает им?
Архитектурно - не уступает.
А абсолютную скорость не мерял. Но думаю что такая же, т.к. и то и то - легковесные обертки непосредственно над АПИ ОСи
Вот тут " Неблокируемые и асинхронные приложения " утверждают, что в libevent используются "epoll на ОС Linux, kqueue на FreeBSD и порты завершения (IOCP) на Windows", а для libev "в ОС Windows используется вызов select" и это якобы медленнее, чем IOCP.
Правда ли это архитектурно и что используется в ASIO: IOCP или select?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208193
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
относительно libev libeventAnatoly Moskovskyпропущено...

Архитектурно - не уступает.
А абсолютную скорость не мерял. Но думаю что такая же, т.к. и то и то - легковесные обертки непосредственно над АПИ ОСи
Вот тут " Неблокируемые и асинхронные приложения " утверждают, что в libevent используются "epoll на ОС Linux, kqueue на FreeBSD и порты завершения (IOCP) на Windows", а для libev "в ОС Windows используется вызов select" и это якобы медленнее, чем IOCP.
Правда ли это архитектурно и что используется в ASIO: IOCP или select?
Несколько лет назад я работал с libevent - под виндой оно умело только select.
Как счас - не знаю, видимо уже сделали, раз говорят об этом :)
Boost.Asio с давних пор (возможно изначально) использует "epoll на ОС Linux, kqueue на FreeBSD и порты завершения (IOCP) на Windows".
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208275
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так вот, чтобы не наркоманствовать с тем, что делает ТС, и придумали nginx, uWSGI и прочие радости.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208310
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZТак вот, чтобы не наркоманствовать с тем, что делает ТС, и придумали nginx, uWSGI и прочие радости.
ну предположим - диплом. Чего сразу - наркоманствовать? Учиться...
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208532
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskykiruhin,

Ну вот у вас бесконечный цикл, в котором при отсутствии данных от клиентов процессор занят на 100%, но ничего полезного не делает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
while(1)
{
	for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
	{
 	    	n = recv(threads[tid].clients[i], buffer, MAX_CLIENT_BUFFER, 0);
 	    	...
	}
	...
}



Используйте функцию select() для выбора сокетов по которым прибыли данные.
Это если просто шоб работало хоть как-то.


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

Что касается

kiruhinесли передать серверу несколько пакетов (передать быстро), то он "склеит" это пакеты в один, как следствие, пакеты невозможно будет разобрать.


То на уровне сокета, пытаться поделить безидейно,
протокол более высокого уровня должен иметь соотвествующие хедеры и (или) трейлеры, якоря
для позиционированя парсера в потоке .
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208556
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если говорить про select() , он должен быть один на все сокеты программе.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208695
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Такой сервер должен просто висеть на select или poll/epoll и ждать ввода-вывода (сетевого), который будет инициирован клиентом.
Как только он возбуждается -- отдавать сокет на обработку рабочему потоку, который должен сделать всё, что нужно, отправить всё клиенту, возможно, и обратно отдать сокет на прослушку select-у или poll/epoll-у.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208722
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот у вас бесконечный цикл, в котором при отсутствии данных от клиентов процессор занят на 100%, но ничего полезного не делает.

Я тут хочу сделать одно замечание. Конечно, busy wait не великолепная штука, конечно, это не очень хорошо. А тут не подходит вообще.
Но вот почему-то все считают его абсолютным неоспариваемым смертным грехом в программировании.
А это совсем не так. Существуют случаи, когда он может быть использован и даже может быть полезен.
Например, как вспомогательный механизм ожидания наряду с событиями, семафорами и пр, или для
того, чтобы не отдавать лишний раз управление другим, если известно, что оно скоро понадобится тебе.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208833
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivА это совсем не так. Существуют случаи, когда он может быть использован и даже может быть полезен.
Например, как вспомогательный механизм ожидания наряду с событиями, семафорами и пр, или для
того, чтобы не отдавать лишний раз управление другим, если известно, что оно скоро понадобится тебе.

Это вопрос дизайна архитектуры .
Нить всеравно когда то отдаст свой контекст выполнения, количество тактов которые делает нить между синхронизирующими событиями должен приблизительно ( хотя бы до порядка) соотвествовать длине контекста выполнения в планировщие,
Я хочу сказать о том, что если управление передается нити , то у нее должно
быть достаточно работы, что бы не греть процессоры спинлоком.
Если появилась необходимость в спинлоках , нужно (желательно ) об этом горомко заявить в консерватории.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208862
ДохтаРMasterZivА это совсем не так. Существуют случаи, когда он может быть использован и даже может быть полезен.
Например, как вспомогательный механизм ожидания наряду с событиями, семафорами и пр, или для
того, чтобы не отдавать лишний раз управление другим, если известно, что оно скоро понадобится тебе.

Это вопрос дизайна архитектуры .
Нить всеравно когда то отдаст свой контекст выполнения, количество тактов которые делает нить между синхронизирующими событиями должен приблизительно ( хотя бы до порядка) соотвествовать длине контекста выполнения в планировщие,
Я хочу сказать о том, что если управление передается нити , то у нее должно
быть достаточно работы, что бы не греть процессоры спинлоком.
Если появилась необходимость в спинлоках , нужно (желательно ) об этом горомко заявить в консерватории.
Есть два варианта:
1. Необходима моментальная реакция на события и некогда ждать пока для нити появиться "достаточно работы". Например брокерская система, где, очевидно, выгодная сделка будет у того, чей сервер первым её вычислит и кинет заявку.
2. Необходима максимальная общая производительность и тут мы действительно можем отдавать контекст в отсутствии задач.

Мало того, нить может почти никогда и не отдавать контекст, будучи привязанной к одному из 32 ядер сервера, на котором помимо ОС только одна эта система и работает.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208880
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРЕсли говорить про select() , он должен быть один на все сокеты программе.

Даже если их больше, чем в него влазит?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208909
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
моментальная реакцияЕсть два варианта:
1. Необходима моментальная реакция на события и некогда ждать пока для нити появиться "достаточно работы". Например брокерская система, где, очевидно, выгодная сделка будет у того, чей сервер первым её вычислит и кинет заявку.


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


моментальная реакцияМало того, нить может почти никогда и не отдавать контекст, будучи привязанной к одному из 32 ядер сервера, на котором помимо ОС только одна эта система и работает.

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

А ввод вывод делается полность асинхронным, что бы не спать , когда есть работа для нити,
пусть ДМА работает.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208917
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Работа, которая описана выше , интересная , но сейчас такой нет, быдлокод кругом.
Грамотная архитектура никому не интересна , за нее не платят.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208945
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovДохтаРЕсли говорить про select() , он должен быть один на все сокеты программе.

Даже если их больше, чем в него влазит?..


Насколько я помню в него помещается 65535 сокетов.
В хайлодае уже на 1024-х на производительности сказывается его псевдоасинхронность.
Дальше дорога в АИО.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38208965
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРНасколько я помню в него помещается 65535 сокетов.

Под линуксами гораздо, гораздо меньше. Но даже при этом меньшем количестве
непропорционально много ЦПУ начинает жрать выяснение "какой же бит установлен".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209006
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovДохтаРНасколько я помню в него помещается 65535 сокетов.

Под линуксами гораздо, гораздо меньше. Но даже при этом меньшем количестве
непропорционально много ЦПУ начинает жрать выяснение "какой же бит установлен".


Я сказал помещается ( можно впихнуть), реально если важен перфоманс
то больше чем 1024 смысла туда запихивать нет, в том числе по причинам вами озвученым( поиск дискриптора).
Можно нарисовать велосипед на тему select на SIGIO.
В свои времена приходилось рисовать заглушку , что бы долавливать SIGIO
прорывающиеся сквозь селект на хайлоаде( не помню , толи на СКО то ли на 2.2 линуксовых ядрах ) .

Правильная хайлоад архитектура должна быть построена на АИО, не зависимо от количества сокетов.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209085
ДохтаРРабота, которая описана выше , интересная , но сейчас такой нет, быдлокод кругом.
Грамотная архитектура никому не интересна , за нее не платят.
Да ладно, сейчас есть задачи и поинтересней. Не пользовательская многозадачность, а хардварная, на GPU с 40000 виртуальных ядер на один чип, и 80000 - 320000 на сервер. И DMA обмен с периферией.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209324
Фотография MedEx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лично я бы выбрал Qt фрейморк 4.8.
Постороение на нём кроссплатформенного "полноприводного", параллельно-многопоточного(QtConcurent) http сервера есть видеоурок на тытрубке.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209495
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаРDimitry Sibiryakovпропущено...

Под линуксами гораздо, гораздо меньше. Но даже при этом меньшем количестве
непропорционально много ЦПУ начинает жрать выяснение "какой же бит установлен".


Я сказал помещается ( можно впихнуть), реально если важен перфоманс
то больше чем 1024 смысла туда запихивать нет, в том числе по причинам вами озвученым( поиск дискриптора).
Можно нарисовать велосипед на тему select на SIGIO.
В свои времена приходилось рисовать заглушку , что бы долавливать SIGIO
прорывающиеся сквозь селект на хайлоаде( не помню , толи на СКО то ли на 2.2 линуксовых ядрах ) .

Правильная хайлоад архитектура должна быть построена на АИО, не зависимо от количества сокетов.
Текущая имплементация aio для сокетов не является асинхронной
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209677
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdДохтаР
Правильная хайлоад архитектура должна быть построена на АИО, не зависимо от количества сокетов.
Текущая имплементация aio для сокетов не является асинхронной


http://www.ibm.com/developerworks/linux/library/l-async/
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209760
WesttrdДохтаРпропущено...


Я сказал помещается ( можно впихнуть), реально если важен перфоманс
то больше чем 1024 смысла туда запихивать нет, в том числе по причинам вами озвученым( поиск дискриптора).
Можно нарисовать велосипед на тему select на SIGIO.
В свои времена приходилось рисовать заглушку , что бы долавливать SIGIO
прорывающиеся сквозь селект на хайлоаде( не помню , толи на СКО то ли на 2.2 линуксовых ядрах ) .

Правильная хайлоад архитектура должна быть построена на АИО, не зависимо от количества сокетов.
Текущая имплементация aio для сокетов не является асинхронной
Имплементация где? И как asynchronous I/O (AIO) может быть не asynchronous?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38209773
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MedEx,

Ну щас все будут перечислять что знают - и boost и qt и glib... Qt - это слишком тяжёлая штука и оверхеда несёт с собой прилично. Нужно что-то более приземлённое. Лучшей пусть свой велосипед лабает вокруг libpthread
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38210099
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имплементация гдеWesttrdпропущено...

Текущая имплементация aio для сокетов не является асинхронной
Имплементация где? И как asynchronous I/O (AIO) может быть не asynchronous?

AIO имеет ряд ограничений, и пока в стандартных ядрах нет полноценной реализации для сетевых сервисов. Вот последняя известная мне информация на сей счет:

http://lse.sourceforge.net/io/aio.html
What Does Not Work?

AIO read and write on files opened without O_DIRECT (i.e. normal buffered filesystem AIO). On ext2, ext3, jfs, xfs and nfs, these do not return an explicit error, but quietly default to synchronous or rather non-AIO behaviour (i.e io_submit waits for I/O to complete in these cases). For most other filesystems, -EINVAL is reported.
AIO fsync (not supported for any filesystem)
AIO read and write on sockets (doesn't return an explicit error, but quietly defaults to synchronous or rather non-AIO behavior)
AIO read and write on pipes (reports -EINVAL)
Not all devices (including TTY) support AIO (typically return -EINVAL)
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38210126
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Westtrd,

Я думаю, ДохтаР имел в виду не AIO как конкретное АПИ в Линуксе, а асинхронную архитектуру в общем, когда пользовательский код запускает задания и обрабатывает результаты, не используя механизм потоков для ожидания выполнения этих заданий.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38210129
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyпользовательский код запускает задания и обрабатывает результаты,
не используя механизм потоков для ожидания выполнения этих заданий.
Угу, автомагически. "А унутре у нея неонка." (с)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38211065
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

Мне тут известны 2 основных направления:
1. epoll для требовательных к латентности решений
2. libev и производные для требовательных к масштабируемости решений

Как правило, универсального ничего нет, решение затачивается индивидуально, особенно в специфичных проектах
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38211220
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdМне тут известны 2 основных направления:
1. epoll для требовательных к латентности решений
2. libev и производные для требовательных к масштабируемости решений

Это одно и то же направление.
2 - более высокоуровневое и кросплатформенное АПИ над 1 и аналогами в других ОСях.

Это и есть AIO (в широком смысле) про которое говорилось выше.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38211381
Anatoly MoskovskyWesttrdМне тут известны 2 основных направления:
1. epoll для требовательных к латентности решений
2. libev и производные для требовательных к масштабируемости решений

Это одно и то же направление.
2 - более высокоуровневое и кросплатформенное АПИ над 1 и аналогами в других ОСях.

Это и есть AIO (в широком смысле) про которое говорилось выше.
Т.е. фактически это (libev, libevent, boost.asio) самый производительный и по латентности, и по масштабируемости способ обмена данными по обычным TCP/IP сетям?


http://alexott.net/ru/cpp/BoostAsioNotes.html] http://alexott.net/ru/cpp/BoostAsioNotes.html
westtrdВозможно даже выгнать ОС с этих ядер, при желании, важно чтобы irqbalance не использовал их, в остальном не страшно.
Вот как раз asio для не самых критичных по латенси компонентов подходит намного лучше того, что вы перечислили. Для критичных вещей я использую хранилища, аналогов которых в общеизвестных библиотеках нет , которые автоматически выравниваются по границе кеш линии процессора, реализуют безлоковую синхронизацию при необходимости.
А какой профит в % или абсолютных величинах это дает и как примерно это выглядит в реализации?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38211424
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про локфри.

В Бусте 1.53 появились несколько локфри контейнеров, в том числе очередь, которая наиболее часто используется для передачи сообщений между потоками.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38212077
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWesttrd,

Я думаю, ДохтаР имел в виду не AIO как конкретное АПИ в Линуксе, а асинхронную архитектуру в общем, когда пользовательский код запускает задания и обрабатывает результаты, не используя механизм потоков для ожидания выполнения этих заданий.

В принципе да.
Но если идти еще глубже в перфоманс ,
то ожидание асинхронно на несколько сокетов, но сама операция read write
сихронна с точки зрения контекста выполнения.


Если расматривать чистый АИО , асихронным будет все,
так как ядро дернет колбек фунцию (sigaction) процесса , когда поменяется
состояние сокета ( что то придет , что то уйдет).
Этим колбеком можно разбудить другую нить для обработки.
Или продолжить обработку самостоятельно с места в котором нить была
прервана колбеком.
Ядро через ДМА пишет читает адресное пространство процесса
паралельно с выполнением самого процесса.
По факту завешения операции ввода вывода дергает колбек.
Изза ДМА всякие ограничения на работу АИО с кешами файловой системы
итд итп.

Приблизительно так.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38212787
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
самый производительный способAnatoly Moskovskyпропущено...

Это одно и то же направление.
2 - более высокоуровневое и кросплатформенное АПИ над 1 и аналогами в других ОСях.

Это и есть AIO (в широком смысле) про которое говорилось выше.
Т.е. фактически это (libev, libevent, boost.asio) самый производительный и по латентности, и по масштабируемости способ обмена данными по обычным TCP/IP сетям?


http://alexott.net/ru/cpp/BoostAsioNotes.html]http://alexott.net/ru/cpp/BoostAsioNotes.html] http://alexott.net/ru/cpp/BoostAsioNotes.html
westtrdВозможно даже выгнать ОС с этих ядер, при желании, важно чтобы irqbalance не использовал их, в остальном не страшно.
Вот как раз asio для не самых критичных по латенси компонентов подходит намного лучше того, что вы перечислили. Для критичных вещей я использую хранилища, аналогов которых в общеизвестных библиотеках нет , которые автоматически выравниваются по границе кеш линии процессора, реализуют безлоковую синхронизацию при необходимости.
А какой профит в % или абсолютных величинах это дает и как примерно это выглядит в реализации?
Тут речь идет не о процентах, тут речь идет скорее всего об узкоспециализированных решениях.
И, понятное дело, их применение должно быть обоснованным и уместным. В критических местах, там где битва идет за наносекунды, это становится необходимым.

Пример из личного опыта, одно из кастомизированных хранилищ моего приготовления дает на страничном рингбуфере указателей пропускную способность более 300 млн сообщений в секунду с одним писателем.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38212821
Westtrdсамый производительный способпропущено...

Т.е. фактически это (libev, libevent, boost.asio) самый производительный и по латентности, и по масштабируемости способ обмена данными по обычным TCP/IP сетям?


http://alexott.net/ru/cpp/BoostAsioNotes.html]http://alexott.net/ru/cpp/BoostAsioNotes.html] http://alexott.net/ru/cpp/BoostAsioNotes.html
пропущено...

А какой профит в % или абсолютных величинах это дает и как примерно это выглядит в реализации?
Тут речь идет не о процентах, тут речь идет скорее всего об узкоспециализированных решениях.
И, понятное дело, их применение должно быть обоснованным и уместным. В критических местах, там где битва идет за наносекунды, это становится необходимым.

Пример из личного опыта, одно из кастомизированных хранилищ моего приготовления дает на страничном рингбуфере указателей пропускную способность более 300 млн сообщений в секунду с одним писателем.
А сколько при этом читателей, размер буфера и сколько CPUs/Cores на системе?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38213567
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
самый производительный способ,

Размер страницы буфера подбирается.
Количество читателей не ограничено, но такие характеристики доступны только на выделенных ядрах в busy spin, при применении нотификаторов такое недоступно, само собой.

Как я уже говорил, решение узкоспециализировано и не рассчитано на массовое применение, его задача - обеспечивать теоретически возможную пропускную способность в критически важных компонентах низколатентных серверных приложений.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38213710
Westtrdсамый производительный способ,

Размер страницы буфера подбирается.
Количество читателей не ограничено, но такие характеристики доступны только на выделенных ядрах в busy spin, при применении нотификаторов такое недоступно, само собой.

Как я уже говорил, решение узкоспециализировано и не рассчитано на массовое применение, его задача - обеспечивать теоретически возможную пропускную способность в критически важных компонентах низколатентных серверных приложений.
Это понятно, что ядра нагружены на 100% и нет переключения потоков.
Интересно вот что. Этот буфер же шарится между ядрами? И вот между сколькими ядрами он у вас шарится при 300млн сообщений (10 тактов = 3 нс на сообщение) и сколько в среднем барьеров памяти на одно сообщение (или сколько сообщений на один барьер)?

Вообще 3нс - это минимальная латентность кэша L2, в лучшем случае шарящегося между двумя соседними ядрами. Т.е. с wait-free вы смогли бы в лучшем случае использовать этот буфер для 2х ядер. А если ядер больше, значит барьеров меньше, чем сообщений.

У вас буфер делиться на несколько буферов по числу ядер и вызывается один барьер на каждый из них, т.е. на пачку сообщений?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38213752
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
самый производительный способ,

Один из принципов в данном случае - все аффинированные ядра должны разделять одну страницу рингбуфера в кеше процессора, иначе все тухнет.

Для курсоров барьеры не пользуются в принципе, алго позволяет это не делать.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38213779
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Westtrd
Для курсоров барьеры не пользуются в принципе, алго позволяет это не делать.


Я прошу прощения, это как ?

Вы нашли кнопку на процессоре
включения-выключения аут_оф_ордер оптимизации ?

Ури , где у него кнопка!!!! Ури !!! Ури !!!

YouTube Video
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38214063
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Проприетарные алгоритмы, вся эта оптимизация устраняется на уровне внутренней логики.
Подробности закрыты.

И да, этот момент весьма тщательно оттестирован и работает.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38214327
Westtrdсамый производительный способ,

Один из принципов в данном случае - все аффинированные ядра должны разделять одну страницу рингбуфера в кеше процессора, иначе все тухнет.
Если точнее, то страницу в LLC(L3) CPU.

WesttrdДля курсоров барьеры не пользуются в принципе, алго позволяет это не делать.
Барьеры в любом случае есть, либо явные - либо неявные. Чтобы доставить изменения из L1/L2 в L3.
Неявные, как вариант, это вытеснение данных из L1/L2. Интересно это может быть быстрее, чем явный барьер?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38214345
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
самый производительный способ,

Согласен.
У меня получается что да.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38217181
WesttrdДля курсоров барьеры не пользуются в принципе, алго позволяет это не делать.
А если это не военная тайно, как вы добились для курсоров отсутствие конкуренции - у каждого читателя свой курсор?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38217638
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
самый производительный способ,

Это решение описано в специализированных проектах - курсор читателя если они не связаны логически, ДОЛЖЕН быть независимым, и оверхеда тут практически никакого
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219423
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Westtrdсамый производительный способ,

Это решение описано в специализированных проектах - курсор читателя если они не связаны логически, ДОЛЖЕН быть независимым, и оверхеда тут практически никакого

Оверхедов может быть 2 вида:

1. Ожидание на блокировке ресурса ( всех или части записей из курсора) , пока его кто то меняет.

2. Копирование курсора в промежуточный буфер ( создание версии снапшота ).

Имхо по другому никак.

Можно еще пойти посредине между 1 и 2 , по которому иногда ходит оракл - рестарт стейтмента,
замена курсора на новую версию снапшота при нарушении логической целостности курсора пришедшей из какой то другой нити ( пользовательской сессии) .
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219811
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Ни первого, ни второго на читателе нет. Блокировок ресурса на курсоре не возникает, ибо курсор однопоточная сущность. В моей парадигме все блокировки контролируются писателем, но они минимизированы.

Копирования курсора тем более нет. Но это особенности имплементации, специфичные для решения.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219813
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Речь идет не об имплементации изменяемого хранилища, а об разновидностях FIFO очередей.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219870
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Westtrd
В моей парадигме все блокировки контролируются писателем, но они минимизированы.


Да, блокировки должны контролироваться писателями.
Но я не исключаю варианта, когда читатель может взять себе обьект в процессе записи.
Особенно если это структура( класс) с множеством полей.
Поэтому ИМХО читатель обязан смотреть на блокировку установленную писателем.
что бы не прочитать мусор, часть обьекта до изменения , другую часть уже измененную.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219877
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Читателю неизвестно о существовании объекта до тех пор, пока он не находится в консистентном состоянии.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38219936
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdДохтаР,

Читателю неизвестно о существовании объекта до тех пор, пока он не находится в консистентном состоянии.

Вы исключаете возможность изменения состояния в процессе работы читателя над обьектом ?
Как писатели узнает о том, что обьект сейчас обрабатывается читателем ?

У вас синхронный конвеер ? ( в один момент времени с обьектом работает одна нить исполнения и по конвееру передает обьект дальше)

Мы ведь вроде как об аснхронной многопоточной обработке говорим .
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220025
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Я писал про исключительно имплементации очередей FIFO.
После попадания в очередь объект, как правило, не изменяется.

В случае, если изменение возможно, применяются иные архитектурные решения.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220050
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdДохтаР,

Я писал про исключительно имплементации очередей FIFO.


Поэтому я задал наводящие вопросы про конвеер, для однозначности понимания.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220151
Westtrdсамый производительный способ,

Это решение описано в специализированных проектах - курсор читателя если они не связаны логически, ДОЛЖЕН быть независимым, и оверхеда тут практически никакого
А как писатель узнает, что читатель уже прочитал данную запись?
И как читатели узнают какие записи им читать, чтобы не было чтений одной записи разными читателями, или они идут с шагом i = n * count_of_readers?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220241
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
читатель уже прочиталИ как читатели узнают какие записи им читать, чтобы не было чтений одной записи разными читателями,

Что бы не получить лост апдейт неконсистентность.
если читатели собираются менять то, что начитали, в зависимости от каких то условий, то тогда да.

Но в большенстве случаев эксклюзивная блокировка на чтение не нужна.
Нужно ставить шаред блокировку, что бы другие читатели могли паралельно читать.
Проверять условия, менять ее на экслюзивную, как у писателя и менять.

Пока на ресурсе есть шаред блокировка все могут читать паралельно никому не мешая ,
но изменять никто не может пока все читающие ее не отпустят.

приблизительно так.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220313
ДохтаРчитатель уже прочиталИ как читатели узнают какие записи им читать, чтобы не было чтений одной записи разными читателями,

Что бы не получить лост апдейт неконсистентность.
если читатели собираются менять то, что начитали, в зависимости от каких то условий, то тогда да.

Но в большенстве случаев эксклюзивная блокировка на чтение не нужна.
Нужно ставить шаред блокировку, что бы другие читатели могли паралельно читать.
Проверять условия, менять ее на экслюзивную, как у писателя и менять.

Пока на ресурсе есть шаред блокировка все могут читать паралельно никому не мешая ,
но изменять никто не может пока все читающие ее не отпустят.

приблизительно так.
Это все понятно. Вопрос не в этом.
Если стоит задача раскидать работу по ядрам, то в любом случае то, что делает одно ядро/поток/читатель не должны делать другие ядра/потоки/читатели.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220481
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
читатель уже прочитал,

А нафига это знать писателю если хранилище статичное?
Архитектура курсора предусматривает знание о том, какой элемент last pop'ped у каждого курсора.

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

It depends, в общем. Но в любом случае это не функционал ни писателя, ни читателя, а хранилища.

Читатели не в курсе про внутреннее строение хранилища, он запрашивает, дай-ка мне указатель на следующий элемент интересующей меня структуры.

В одновременном чтении несколькими читателями одной и той же записи не вижу никакой проблемы, хотя в критичных местах это нежелательно, тогда архитектура разбивается на последовательные однопоточные участки с моделью отношений 1P-1C
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220483
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
раскидать работу по ядрам,

Это вопрос правильной имплементации архитектуры.
Когда требование FIFO принципиально, как правило, о распараллеливании речи идти не может или же это по критериям производительности неуместно.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220756
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Westtrdдай-ка мне указатель на следующий элемент интересующей меня структуры.
А почему вы считаете что тут можно без барьеров обойтись?
А если в очередь будет добавлен указатель на структуру, а сама структура еще не синхронизирована по всем ядрам?
Барьеры решают именно подобные проблемы.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220779
Westtrdчитатель уже прочитал,

А нафига это знать писателю если хранилище статичное?
Архитектура курсора предусматривает знание о том, какой элемент last pop'ped у каждого курсора.
Хранилище имеет конечный размер и когда-то закончится, значит нужен re-use, и писатель должен знать можно уже перезаписывать элемент или нельзя, т.е. писатель должен знать позицию курсора каждого читателя.
А для этого каждый читатель должен будет после каждого сдвига курсора делать store barrier или надеяться на то, что хранилище никогда не переполниться с потерей записей.

WesttrdВ одновременном чтении несколькими читателями одной и той же записи не вижу никакой проблемы, хотя в критичных местах это нежелательно, тогда архитектура разбивается на последовательные однопоточные участки с моделью отношений 1P-1C
Если задача стоит каждому читателю читать каждую запись, то да - проблемы нет. Но если стоит задача, где писатель должен раздавать задачи, которые должны брать свободные на данный момент читатели - то проблема.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220799
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

Это не страшно, и решается внутренней логикой.
Барьеры негативно влияют на латенси, в данном случае работа на спине часто выгоднее.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220804
Westtrdраскидать работу по ядрам,

Это вопрос правильной имплементации архитектуры.
Когда требование FIFO принципиально, как правило, о распараллеливании речи идти не может или же это по критериям производительности неуместно.
Если все читатели и писатель работают в пределах одного ядра, и распараллеливание не требуется, то может подойдут corutines, которые советует Anatoly Moskovsky.
А если читатели и писатель раскиданы по ядрам, и пусть даже все читатели читают одни и те же записи, то в любом случае одни читатели будут опережать других, и кто-то уже все прочитал, а кто-то только первый элемент, и об этом должен будет знать писатель перед тем, как затереть этот элемент при переполнении хранилища.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220809
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
переполниться с потерей записей,

1. Хранилище страничное.
2. Вариант повторного использования с очисткой и инвалидацией курсора предусмотрен.

Как правило, мои приложения выполняются на системе с достаточным количеством RAM. Обычно в 50 и более раз нежели известная пиковая нагрузка.

По второй части соглашусь, но я бы это делал не на стороне писателя, а на стороне читателя чз диспетчера читателей. Тут и батчинг работает и подобного рода вещи.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220813
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdЭто не страшно, и решается внутренней логикой.
Что значит не страшно?
Вам что все равно какие данные увидит читатель, новые или те которые он по этому адресу в прошлый раз читал?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220818
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
читатели и писатель раскиданы,

Писателю все равно, что там делают читатели. Вы при создании хранилища устанавливаете стратегию управления страницами.

Если страницы повторно используются, писатель имеет значения курсора читателей и время заполнения страницы с опциональной очисткой после разрешенного интервала.

Занимается этим фоновый менеджер хранилища.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220821
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

Данные после добавления не изменяются.
Это FIFO.

До приведения записи в консистентное состояние читатель об этом не узнает в принципе.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220822
Anatoly MoskovskyWesttrdдай-ка мне указатель на следующий элемент интересующей меня структуры.
А почему вы считаете что тут можно без барьеров обойтись?
А если в очередь будет добавлен указатель на структуру, а сама структура еще не синхронизирована по всем ядрам?
Барьеры решают именно подобные проблемы.
Вряд ли Westtrd сознается, но что-то подсказывает, что там вся надежда на неявные барьеры при вытеснении кэша, вероятность которых высока на относительно большом размере хранилища.
Можно конечно их вызов вручную детерминировать, допустим для условия - каждые 64КБ или 1мкс, но этож надо самому писать, а вытеснение автоматически. Только вот нюанс, есть условия при которых оно не сработает.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220827
WesttrdКак правило, мои приложения выполняются на системе с достаточным количеством RAM. Обычно в 50 и более раз нежели известная пиковая нагрузка.
А ну вот я про это и говорил. Тут некоторые вещи упрощаются. А переполнение в принципе не предусмотрено, или при нем включается другая стратегия работы хранилища?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220829
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
большом размере хранилища,

Это не военная тайна, описано в проектах, то есть тут эксплуатируется тот факт, что при существенной интенсивности потока сообщений это происходит с высокой вероятностью, и в отношении латенси это значительно выгоднее барьеров.

Кроме того, думающий админ повесит писателя и читателя этого хранилища на ядра одного процессора.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220830
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WesttrdДо приведения записи в консистентное состояние читатель об этом не узнает в принципе.
А что вы понимаете под консистентным состоянием записи?
Если запись больше одного машинного слова, то даже если вы ее полностью сформировали на одном ядре, то на другом ядре она может быть лишь частично сформирована.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220831
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
некоторые вещи упрощаются,

В принципе не предусмотрено. Пока не вижу реальным, честно говоря, и не стал разрабатывать подобную архитектуру, но при необходимости архитектура безболезненно и невидимо для пользовательского кода трансформируется к данному функциональному требованию.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220834
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

Курсор контролируется хранилищем, хранилище осведомлено о том, когда запись переходит в консистентное состояние.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220841
Westtrdбольшом размере хранилища,

Это не военная тайна, описано в проектах, то есть тут эксплуатируется тот факт, что при существенной интенсивности потока сообщений это происходит с высокой вероятностью, и в отношении латенси это значительно выгоднее барьеров.

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

Повесить всех читателей и писателя на одно ядро? Насколько я помню потоки на ядре переключаются примерно раз в 1мс, т.е. это сразу +(1мс X кол-во читателей) к задержке.
Синхронизация двух ядер через LLC(L3) с барьером 30нс, т.е. минимум в 30 000 раз меньше.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220844
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
читателей и писателя на одно ядр,

Основная модель - 1P-1C
Ключевые фиды мессаджинга работают на выделенных процессорных ядрах.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220848
Westtrdчитателей и писателя на одно ядр,

Основная модель - 1P-1C
Ключевые фиды мессаджинга работают на выделенных процессорных ядрах.
А почему для 1P-1C не используете coroutines?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220854
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не используете coroutines?,

Опыт показал худшие результаты.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220856
Westtrdне используете coroutines?,

Опыт показал худшие результаты.
Не профилировали в чем их затык и оверхед?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38220884
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в чем их затык и оверхед?,

Управление остановкой и возобновлением треда
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221009
Westtrdв чем их затык и оверхед?,

Управление остановкой и возобновлением треда
Anatoly Moskovsky , ну вот, а вы говорили coroutines легкие и быстрые :)
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221014
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
coroutines легкие и быстрые,

Мы ж код не видели.
Может он их создавал непосредственно при вызове, а не заранее.
Создание coroutine содержит оверхед на создание стека, т.е. выделение в куче и в ОСи соответствующих блоков памяти. Это не так много как оверхед создания обычного потока, но и не мало.

Но переключение контекста между двумя уже созданными coroutine имеет оверхед в виде копирования нескольких регистров (причем не всех) в память и обратно - не знаю что тут может быть медленным.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221059
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskycoroutines легкие и быстрые,

Мы ж код не видели.
Может он их создавал непосредственно при вызове, а не заранее.
Создание coroutine содержит оверхед на создание стека, т.е. выделение в куче и в ОСи соответствующих блоков памяти. Это не так много как оверхед создания обычного потока, но и не мало.

Но переключение контекста между двумя уже созданными coroutine имеет оверхед в виде копирования нескольких регистров (причем не всех) в память и обратно - не знаю что тут может быть медленным.

Мне кажется что мы пытаемся экономить на спичках .

Переключение контекста нитей тербует
востановление состояния всех регистров.
Затраты соизмеримы с вызовом-выходом_из функции.
Это спички.

Гораздо больше ресурсов в том числе и как минимум 2 барьера
дожно уйти на вычисление ,
какой из нитей или конитей когда передавать управление
и куда ( на какое ядро).
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221082
ДохтаРAnatoly Moskovskycoroutines легкие и быстрые,

Мы ж код не видели.
Может он их создавал непосредственно при вызове, а не заранее.
Создание coroutine содержит оверхед на создание стека, т.е. выделение в куче и в ОСи соответствующих блоков памяти. Это не так много как оверхед создания обычного потока, но и не мало.

Но переключение контекста между двумя уже созданными coroutine имеет оверхед в виде копирования нескольких регистров (причем не всех) в память и обратно - не знаю что тут может быть медленным.

Мне кажется что мы пытаемся экономить на спичках .
А у Westtrd своё хранилище оказалось заметно быстрее использования готовых корутинов.

ДохтаРПереключение контекста нитей тербует
востановление состояния всех регистров.
Затраты соизмеримы с вызовом-выходом_из функции.
Это спички.

Гораздо больше ресурсов в том числе и как минимум 2 барьера
дожно уйти на вычисление ,
какой из нитей или конитей когда передавать управление
и куда ( на какое ядро).
Ещё достаточно большая часть кэша должна быть обновлена, подгружены новые PE в TLB. Но все это мелочи по сравнению с редкой частотой переключения контекста не позволяющей делать low latency обработку.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221099
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

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

Я не говорю о том, что читатель всегда медленнее, но тем не менее.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221100
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
своё хранилище,

Все верно, но для меня было еще важно не столько достичь средней латенси на хорошем уровне, но и получить некие гарантии, что не будет существенных спайков.

Изложенный механизм это позволил сделать. Пока это моя Конституция ) Далее время покажет.

Хотя это очень специализированное решение, и глупо было бы его распространять на все попавшиеся под руку случаи.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221120
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

В ULL выделение ресурсов на лету считается дурным тоном :)
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221122
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
своё хранилищеДохтаРпропущено...


Мне кажется что мы пытаемся экономить на спичках .
А у Westtrd своё хранилище оказалось заметно быстрее использования готовых корутинов.



Когда стоит вопрос выбора красивый-умный ( производительный-надежный)
Я бы ИМХО выбирал умный.
Закладывая мутексы барьеры переключения контекстов
итд в разумном количестве ,
до того как возникнут проблемы с происком UB в логике приложения.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38221143
Westtrd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

Решение, безусловно, специализированное
И таргетированное на совершенно конкретную микроархитектуру, так оно и собирается, с соответствующей оптимизацией.

Насчет UB. Жесточайшие юниттесты с динамически изменяемой нагрузкой пока ничего не выявили.
И в дебаге стоит немереное количество ассертов.

Риски все поняты, измерены и приняты, цели высокие и жертвы понятны.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315160
Anatoly MoskovskyПро локфри.

В Бусте 1.53 появились несколько локфри контейнеров, в том числе очередь, которая наиболее часто используется для передачи сообщений между потоками.
А сейчас эти lock-free контейнеры используются в самой boost.asio 1.53 - 1.54beta или собираются их использовать в будущих реализациях boost.asio?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315170
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lock-free контейнеры,

В 1.53 на библиотеку lockfree нет ссылок из других библиотек.
Про намерения - не в курсе.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315180
Anatoly Moskovskylock-free контейнеры,

В 1.53 на библиотеку lockfree нет ссылок из других библиотек.
Про намерения - не в курсе.
А что сейчас используется в boost.asio для "раскидывания" задач по потокам из пула, обычная очередь с мьютексом?
Она одна или на каждый поток из пула своя блокировочная очередь, чтобы можно было через post() из разных потоков ставить задачи в очередь выполняющего потока?
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315283
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lock-free контейнеры,

Насколько я помню, очередь одна на все потоки и защищена стандартным мьютексом.
Лень копаться в коде, чтобы перепроверить это.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315289
Anatoly Moskovskylock-free контейнеры,

Насколько я помню, очередь одна на все потоки и защищена стандартным мьютексом.
Лень копаться в коде, чтобы перепроверить это.
Т.е. "по легенде" освободившийся поток сам берет себе из этой общей очереди очередное задание?
По идее тогда проблем не должно было быть с заменой lock-based очереди на lock-free.
...
Рейтинг: 0 / 0
Потоковый сервер на С++
    #38315297
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lock-free контейнерыПо идее тогда проблем не должно было быть с заменой lock-based очереди на lock-free.
Сначала нужно доказать, что вообще будет выигрыш от такой замены :)
...
Рейтинг: 0 / 0
94 сообщений из 94, показаны все 4 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Потоковый сервер на С++
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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