2017-05-05 84 views
0

我知道如何扭轉字節順序(convert big endian to little endian in C [without using provided func]) - 在這種情況下,我想使用__builtin_bswap64複製字節反轉uint64_t中以uint8_t數組

我也知道如何將一個64位UINT複製到一個字符數組 - 理想的記憶體。 (How do I convert a 64bit integer to a char array and back?

我的問題是這兩種的結合。在問題的根源,我試圖找到這段代碼更快的替代方案:

carr[33] = ((some64bitvalue >> 56) & 0xFF) ; 
carr[34] = ((some64bitvalue >> 48) & 0xFF) ; 
carr[35] = ((some64bitvalue >> 40) & 0xFF) ; 
carr[36] = ((some64bitvalue >> 32) & 0xFF) ; 
carr[37] = ((some64bitvalue >> 24) & 0xFF) ; 
carr[38] = ((some64bitvalue >> 16) & 0xFF) ; 
carr[39] = ((some64bitvalue >> 8) & 0xFF) ; 
carr[40] = (some64bitvalue & 0XFF); 

由於存儲器複製不採取__builtin_bswap64源論證的結果(?或者它),我想這:

*(uint64_t *)upub+33 = __builtin_bswap64(some64bitvalue); 

,但我最終的 錯誤:左值要求作爲分配的左操作數

是否有快速替代原來的代碼我想在所有的更換?

+0

什麼的'upub'類型?您可能違反了嚴格的別名規則。 – user694733

+0

爲什麼你認爲它太慢?你有沒有看看彙編代碼?你有個人資料嗎?首先集中編寫便攜和可讀代碼(例如,通過將其封裝在一個函數中),只有在遇到速度問題時才進行優化。 – Olaf

+0

我確實有速度問題,我知道「過早優化問題」。這裏不適用。我的假設完全基於直覺,但基於'*((uint64_t *)upub + 33)= __builtin_bswap64(大約64bitval);'我的直覺證明是正確的。 – Perlator

回答

3

此:

*(uint64_t *)upub+33 = __builtin_bswap64(PplusQ[di][3]); 

解析作爲

(*(uint64_t *) upub) + 33 = __builtin_bswap64(PplusQ[di][3]); 

所以左手側是uint64_t,不是左值。

所以將這項工作?

*(uint64_t *) (upub+33) = __builtin_bswap64(PplusQ[di][3]); 

還是你的意思是投upubuint64_t *第一,因爲阿空加瓜評論?

*((uint64_t *) upub + 33) = __builtin_bswap64(PplusQ[di][3]); 

我沒有看到提到的upub的類型,所以我不能說。

另外,我有一種感覺,有可能是與aliasing rules如果upub原本指向另一種類型的問題,所以你可能想通過工會使用類似gcc的-fno-strict-aliasing或進行分配,或者在一個字節就像你的第一個代碼片段一樣。

+0

什麼是'upub'?取決於如何聲明/設置,這可以並將調用UB。 – Olaf

+0

@Olaf,我們不知道,問題沒有說明。我以爲我提到信息丟失了,我還想過我提到了可能的別名問題?我很樂意看到這方面的驗證。 – ilkkachu

+0

upub/carr是**,如標題所示** uchar' /'uint8_t'數組。 '*(uint64_t *)(upub + 33)= __builtin_bswap64(PplusQ [di] [3]);'適用於所有警告,迂腐和其他哨聲啓用。它也比原始代碼更快。 – Perlator

1

可以複製爲:

uint64_t tmp = __builtin_bswap64(some64bitvalue); 
memcpy(upub+33,&tmp,sizeof(tmp)); 

假設upub是指針變量

+0

工程,但比原始代碼慢。 – Perlator

1

當寫入端無關的代碼不存在的替代比特移位。你的代碼可能已經接近理想。

你可以玩的是使用循環而不是硬編碼的數字。沿此線的東西:

for(uint_fast8_t i=0; i<8; i++) 
{ 
    carr[i+offset] = (some64bitvalue >> (56-(i*8)) & 0xFF; 
} 

這可能會變成慢或快於或等於相比,你已經擁有,取決於系統。總體而言,在沒有考慮特定系統的情況下討論像這樣的手動優化沒有任何意義。