В приложении HFT-трейдинга мне нужно получать данные из многоадресного сокета udp. Единственное требование — задержка — это так важно, что я могу «потратить» одно ядро процессора. Это нормально вращаться или что-то еще. Это то, что я сейчас имею в Windows:
void Receiver::ThreadMethod() {
//UINT32 seq;
sockaddr_in Sender;
int SenderAddrSize = sizeof(Sender);
while (stayConnected) {
int res=recvfrom(socketId,buf,sizeof(char) * RECEIVE_BUFFER_SIZE,0, (SOCKADDR *)& Sender, &SenderAddrSize);
if (res == SOCKET_ERROR) {
printf("recvfrom failed, WSAGetLastError: %d\n", WSAGetLastError());
continue;
}
//seq = *(UINT32*)buf;
//printf("%12s:seq=%6d:len=%4d\n", inet_ntoa(Sender.sin_addr), seq, res);
unsigned char* buf2 = reinterpret_cast<unsigned char*>(buf);
feed->ProcessMessage(res, buf2);
}
}
recvfrom
блоки, так что это будет, вероятно, очень медленно (или я ошибаюсь?). Я должен переписать это для Linux и добиться максимальной задержки. Мне нужно обрабатывать только один сокет на поток, поэтому я предполагаю, что я не должен использовать epoll
поскольку это разработано больше, чтобы обработать много сокетов. Что я должен использовать?
обн я нашел похожий вопрос Низкое время ожидания чтения UDP-порта
В UNIX вы должны использовать fcntl
чтобы ваш сокет не блокировался:
fcntl(socket, F_SETFL, O_NONBLOCK);
Кроме того, если вашему клиенту необходимо обработать несколько сокетов (например, объединить несколько каналов), вы должны использовать select
вызовите обработку нескольких файловых дескрипторов одновременно и посмотрите, какой сокет имеет доступные данные, если таковые имеются (это, помимо прочего, позволит избежать зацикливания всех сокетов даром)
Что касается задержки, другие факторы, такие как тип и конфигурация сетевого адаптера, параметры ядра (возможно, имеющие сетевой адаптер, обходящий ядро) будут оказывать значительное влияние на задержку (подлежит измерению).