2017-02-23 26 views
0

假設我正在構建一個字節數組來通過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發送數據以避免性能命中時,將字對齊所有整數/浮點數是否很常見?在上面的例子中,最好是將字符串的長度擴展到8,這樣下一個可用的字節是字對齊的? memcpy是否提供了自動補償字對齊的更多方法?

+0

投射與對齊要求不匹配的指針不僅僅是性能問題 - 它具有未定義的行爲 - 即使在您認爲處理器支持未對齊數據訪問的平臺上也是如此。 'memcpy'是正確的事情;編譯器可以在安全的情況下優化'memcpy'。 –

+0

你的問題不清楚。你必須遵守使用的協議。但是你的方法是特定於實現並且是一個糟糕的方法正確序列化整數。如果你真的不明白他們的意思,不要使用演員。 – Olaf

+0

@Olaf我有點困惑。發送者和接收者都知道正確的偏移和數據類型。接收器將收到一個字節數組,然後必須按照約定的消息格式進行解碼。 – Izzo

回答

2

不,你真的不會得到性能改進,因爲comms程序用於接收任意二進制流,其中整數的末尾顛倒或者它們沒有對齊。

只是說什麼是位,是什麼意思。

1

我認爲打包數據時性能會下降嗎?

這取決於哪個CPU和其他因素(如4個字節是否跨越緩存行邊界);還取決於如何實施memcpy()

但是,我仍然試圖讀取一個不是字對齊的整數。

否語義上,memcpy()複製字節,並且您正在複製四個字節(其中任何字節不能錯位)。

在實踐中memcpy()可能會被優化以更有效地工作(並且可能從一個大的緩慢混亂開始,它決定它是否可以/不能更有效地工作,結果使它比僅僅做「天真」事情對於小內存拷貝);但是無法控制較低層次的細節,例如這是您爲了便於不必處理較低級別的細節而付出的代價。

當在TCP/IP上發送數據以避免性能命中時,將字對齊所有整數/浮點數是否常見?

把整數放在數據包的開頭,這樣它總是在同一個地方,而不管字符串長度如何(最終總是對齊)將是「更常見」的做法。

另請注意,這並不能解決「endian」(字節順序)問題。要解決endian問題,您需要在定義網絡協議的規範中指定「big endian」或「little endian」;如果這是「大端」,那麼你需要使用像hton()(這會導致在幾乎每臺計算機上都有輕微的性能下降),如果它是「小端」,那麼你將不得不寫無論如何,當主機CPU是小端時,您希望自由轉換(優化爲無)。解決端對端問題的一種方法是將其分解爲字節(如buffer[7] = x; buffer[8] = x >> 8; buffer[9] = x >> 16; buffer[10] = x >> 24;),它解決了對齊問題,但僅適用於無符號整數(「有符號整數的右移」是未定義的行爲)。

相關問題