我想要使結構形式/佈局更「定義/固定」和更少「直到編譯器的判斷」。在x86_64和ARMv7-A體系結構之間進行通信時,結構佈局將被共享。是的,它通常不是可移植的,但對於這個更受限制的情況,字節序是相同的(如果決定在不同的平臺上使用,可以轉換)。C++結構成員對齊和包裝要求在ARM
ARMv7-A上的不同數據類型/大小是否存在對齊要求?(即濫用它們是未定義的行爲)
或者它可以將它們打包到任何對齊?(即它是所有定義的行爲)
做一些路線比其他路線有更好的表現嗎?
我一直在閱讀ARM的包裝/對齊要求,但不幸的是我發現它相對於我的架構有點過時。 http://www.aleph1.co.uk/chapter-10-arm-structured-alignment-faq
我一直在使用這樣的標題,兩種體系結構:
#pragma pack(4)
struct foo
{
uint8_t bar1; // 1 byte, the 3 padding bytes
std::array<double,1> bar2; // 8 bytes
};
#pragma pack()
我使用GCC交叉編譯器,ARM:gcc -Wall -Wextra -Wcast-align -march=armv7-a -mfloat-abi=softfp -mfpu=neon -mtune=cortex-a9
當我打電話foo abc; abc.bar2.data();
,並與-fsanitize=undefined -fsanitize=address
編譯產生運行時錯誤:
runtime error: member call on misaligned address 0xbeeb0c44 for type 'struct array', which requires 8 byte alignment
0xbeeb0c44: note: pointer points here
01 00 00 00 03 00 00 00 03 00 00 00 01 00 00 00 f4 0d eb be fc 0d eb be c0 a5 00 00 00 00 db 4b
^
/sysroot.../usr/include/c++/5.2.0/array:230:32: runtime error: reference binding to misaligned address 0xbeeb0c44 for type 'const double', which requires 8 byte alignment
0xbeeb0c44: note: pointer points here
01 00 00 00 03 00 00 00 03 00 00 00 01 00 00 00 f4 0d eb be fc 0d eb be c0 a5 00 00 00 00 db 4b
^
我喜歡相信saniti ser,這讓我覺得這很糟糕。但是,如果我關閉衛生器並優化至-O3
,則表現正常。不過,我可能只是(非)幸運的,而這種未定義的行爲似乎工作正常。我記得早些時候,我已經打包了(1)而不是pack(4)時觸發了-Wcast-align警告,但我不記得我是如何訪問它來觸發的。我認爲這也表明它可能是未定義的行爲。 這個架構的地址管理器和-Wcast-align是否表示了未定義的行爲,即使它看起來有效?
是否建議增加包裝(8)以解決未定義的行爲?不幸的是增加了內存使用量。
最後,是pragma pack(n)
或__attribute__((packed))
爲每個結構實體這樣做的首選方式?(__attribute__((packed))
是GCC擴展,不幸的是無法指定包的大小。)
在ARM上是否故障可能因頁表設置而異;對強烈排序或設備內存的未對齊訪問將始終發生故障,即使未對齊正常內存訪問也是如此。對於不太可能導致問題的「正常」應用程序,但可以在系統級軟件中獲得樂趣。 – solidpixel
謝謝。但是,訂單確實重要,不能任意訂購。在結構的開頭應該有一個小的校驗和,它不能改變位置。 於是問題就變成了:如何找出實現的ABI的對齊需求? –
@ Isogen74:在頁面錯誤/緩存未命中時出現「故障」?或者如I/O故障? 請定義術語「強烈排序」,「設備內存」,「正常內存」。謝謝。 –