在单字节数组中对齐混合字符串和整数数据的方法有哪些?
What are methods for aligning mixed string and integer data within a single byte array?
假设我正在构建一个字节数组以通过 TCP/IP 发送数据。此字节数组包含一个字符串(以空字符结尾的字符数组)以及一个附加到末尾的整数。
所以让我们这样做吧。
char buffer[24]; // buffer that will be sent over TCP/IP
char hello[7] = "hello"
int x = 12; // int is 4 bytes
现在假设我执行了一个 memcpy。
memcpy(buffer, hello, 7); // 7 force null character to be copied
memcpy(buffer+7, &x, 4);
通过这样做,我相信我正在将一个整数写入非字对齐地址。我假设这会影响打包数据时的性能?
现在让我们想象一下,我将这些数据发送出去,然后在另一台计算机上接收它。当我继续并解包数据时,我将需要执行正确的转换。但是,我仍在尝试读取一个未按字对齐的整数。这将再次成为性能打击。我可以想象,如果我有一个全部未对齐的整数数组,这种性能损失会增加。
所以我的问题是:当通过 TCP/IP 发送数据时,是否通常的做法是将所有 integers/floats 字对齐以避免性能下降?在我上面说明的情况下,最好将字符串的长度扩展到大小 8,以便下一个可用字节是字对齐的吗? memcpy 是否提供任何进一步的方法来自动补偿单词对齐?
不,您不会真正获得性能改进,因为通信程序用于接收任意二进制流,其中整数的字节序颠倒或它们没有对齐。
只需说出这些位是什么以及它们的含义。
I assume this would be a performance hit when packaging the data?
这取决于哪个 CPU 和其他因素(比如 4 个字节是否跨越缓存行边界);并且还取决于 memcpy()
的实施方式。
However, I'm still attempting to read an integer that isn't word aligned.
没有。从语义上讲,memcpy()
复制字节,而您正在复制四个字节(其中任何字节都不能错位)。
在实践中 memcpy()
可能会被优化以更有效地工作(并且可能从一个大的缓慢的混乱开始,决定它是否 can/can 不能更有效地工作最终使它比只是为小内存副本做 "naive" 事情);但是不能像这样控制较低级别的细节是您为不必处理较低级别细节的便利而付出的代价。
Is it common practice to word align all integers/floats when sending data over TCP/IP to avoid performance hits?
将整数放在数据包的开头是 "more common" 的做法,这样无论字符串的长度如何它总是在同一个位置(并且最终也总是对齐的)。
另请注意,这并不能解决 "endian"(字节顺序)问题。要解决端序问题,您需要在定义网络协议的规范中指定 "big endian" 或 "little endian";如果那是 "big-endian" 那么你需要使用类似 hton()
的东西(这将对几乎每台重要的计算机造成轻微的性能影响),如果它是 "little-endian" 那么你要去必须编写自己的转换,希望在主机 CPU 无论如何都是小端时是免费的(优化为无)。解决字节序问题的一种方法是将其分解为字节(如 buffer[7] = x; buffer[8] = x >> 8; buffer[9] = x >> 16; buffer[10] = x >> 24;
),这解决了对齐问题,但仅适用于无符号整数("right shift of signed integer" 是未定义的行为)。
假设我正在构建一个字节数组以通过 TCP/IP 发送数据。此字节数组包含一个字符串(以空字符结尾的字符数组)以及一个附加到末尾的整数。
所以让我们这样做吧。
char buffer[24]; // buffer that will be sent over TCP/IP
char hello[7] = "hello"
int x = 12; // int is 4 bytes
现在假设我执行了一个 memcpy。
memcpy(buffer, hello, 7); // 7 force null character to be copied
memcpy(buffer+7, &x, 4);
通过这样做,我相信我正在将一个整数写入非字对齐地址。我假设这会影响打包数据时的性能?
现在让我们想象一下,我将这些数据发送出去,然后在另一台计算机上接收它。当我继续并解包数据时,我将需要执行正确的转换。但是,我仍在尝试读取一个未按字对齐的整数。这将再次成为性能打击。我可以想象,如果我有一个全部未对齐的整数数组,这种性能损失会增加。
所以我的问题是:当通过 TCP/IP 发送数据时,是否通常的做法是将所有 integers/floats 字对齐以避免性能下降?在我上面说明的情况下,最好将字符串的长度扩展到大小 8,以便下一个可用字节是字对齐的吗? memcpy 是否提供任何进一步的方法来自动补偿单词对齐?
不,您不会真正获得性能改进,因为通信程序用于接收任意二进制流,其中整数的字节序颠倒或它们没有对齐。
只需说出这些位是什么以及它们的含义。
I assume this would be a performance hit when packaging the data?
这取决于哪个 CPU 和其他因素(比如 4 个字节是否跨越缓存行边界);并且还取决于 memcpy()
的实施方式。
However, I'm still attempting to read an integer that isn't word aligned.
没有。从语义上讲,memcpy()
复制字节,而您正在复制四个字节(其中任何字节都不能错位)。
在实践中 memcpy()
可能会被优化以更有效地工作(并且可能从一个大的缓慢的混乱开始,决定它是否 can/can 不能更有效地工作最终使它比只是为小内存副本做 "naive" 事情);但是不能像这样控制较低级别的细节是您为不必处理较低级别细节的便利而付出的代价。
Is it common practice to word align all integers/floats when sending data over TCP/IP to avoid performance hits?
将整数放在数据包的开头是 "more common" 的做法,这样无论字符串的长度如何它总是在同一个位置(并且最终也总是对齐的)。
另请注意,这并不能解决 "endian"(字节顺序)问题。要解决端序问题,您需要在定义网络协议的规范中指定 "big endian" 或 "little endian";如果那是 "big-endian" 那么你需要使用类似 hton()
的东西(这将对几乎每台重要的计算机造成轻微的性能影响),如果它是 "little-endian" 那么你要去必须编写自己的转换,希望在主机 CPU 无论如何都是小端时是免费的(优化为无)。解决字节序问题的一种方法是将其分解为字节(如 buffer[7] = x; buffer[8] = x >> 8; buffer[9] = x >> 16; buffer[10] = x >> 24;
),这解决了对齐问题,但仅适用于无符号整数("right shift of signed integer" 是未定义的行为)。