我目前正在开发一个使用面向连接的 SCTP 的服务器来为少数客户端提供服务。在用一个简单的实现完成第一个原型之后,我现在正在分析应用程序以进行优化。事实证明,CPU 时间的两个主要消耗者之一是网络部分。
关于我实现的应用层协议的效率有两个问题:
1) 数据包大小
目前,我使用的最大数据包大小为 64 字节。您可以找到许多讨论数据包大小的帖子太大,但它们会不会太小?由于 SCTP 允许我一次读取一个数据包 - 类似于 UPD - 同时保证按顺序交付 - 类似于 TCP - 这显着简化了实现。但是,如果我理解正确,每次发送数据包都会花费一个系统调用。系统调用的数量是否会对性能产生重大影响?我可以通过以更大的数据包(即 1024 - 8192 字节)的形式发送消息来减少大量 CPU 周期吗?
2)读取和写入缓冲区
我目前正在使用 memcpy 将数据移入和移出应用程序级网络缓冲区。我发现了许多关于什么是更有效的、memcpy 或正常分配的相互矛盾的帖子。我想知道在这种情况下,一种方法是否会比另一种方法快得多:
选项1
void Network::ReceivePacket(char* packet)
{
uint8_t param1;
uint16_t param2
uint32_t param3;
memcpy(¶m1, packet, 1);
memcpy(¶m2, packet+1, 2);
memcpy(¶m3, packet+3, 4);
// Handle the packet here
}
void Network::SendPacket(uint8_t param1, uint16_t param2, uint32_t param3)
{
char packet[7]
memcpy(&packet, ¶m1, 1);
memcpy(&packet+1, ¶m2, 2);
memcpy(&packet+3, ¶m3, 4);
// Send the packet here
}
选项 2
void Network::ReceivePacket(char* packet)
{
uint8_t param1;
uint16_t param2
uint32_t param3;
param1 = *((uint8_t*)packet);
param2 = *((uint16_t*)packet+1);
param3 = *((uint32_t*)packet+3);
// Handle the packet here
}
void Network::SendPacket(uint8_t param1, uint16_t param2, uint32_t param3)
{
char packet[7]
*((uint8_t*)packet) = param1;
*((uint16_t*)packet+1) = param2;
*((uint32_t*)packet+3) = param3;
// Send the packet here
}
第一个对我来说似乎更干净,但我发现很多帖子表明第二个可能快得多。
当然欢迎任何形式的反馈。