2013-07-30 40 views
1

所以我必須處理一些結構數據,我不得不以MPI_Send/Recv的奇怪方式進行壓縮。對原始數據的指針運算

沒有辦法將它舒適地投射到一個指向我想要操作的已知類型的指針上,然後索引(因爲我已經將結構擠壓成連續數據,不能假定任何關於對齊的東西),所以我必須通過指針算術來完成它。問題是,爲了與MPI保持一致,這些數據被賦予void *,void *上的指針運算是非法的。

我的問題主要是風格:有沒有更好的方法來做到這一點比鑄造char *,然後做我的指針算術?如何將效率考慮在一個void *中,鑄造成char *,做我的東西,然後再回到void *?我無法想象這些指針會非常昂貴。

G'day和thankee很多。

回答

3

指針演員是完全免費的。做到這一點。

具有類型的指針完全是語言級別的概念。當你進入硬件級時,指針只是一個恰好用作內存地址的整數。

必須小心嚴格別名,鑄造約三分球的時候,但char *被定義爲是安全的,我想。

[好的,在某些體系結構中,有些情況下指針的特殊處理超出了「僅僅是整數」的範圍,但您可能會忽略這些情況。也有一些ABI在其中不同的指針類型不同(例如FDPIC),但又是別人的問題。]

+0

啊,那很簡單。非常感謝你。 –

0

您的解決方案是健全的。很多時候,我已經做了這樣的事情:

void handle_raw(void* data) { 
    // Use a uint8_t so pointer arithmetic is at a byte-level. 
    uint8_t* p = data;  
    uint16_t value; 

    // Read a 2-byte value at an arbitrary offset. 
    value = *(uint16_t*)(p + 0x42); 

    // Write a 2-byte value at an arbitrary offset. 
    *(uint32_t*)(p + 0x12) = 0xDEADBEEF; 
} 

當然,你應該使用常數偏移,並執行正確的邊界檢查。

+0

在這種情況下,**不是**安全的。在許多體系結構中,如果指針不是2字節對齊,則代碼將失敗。此外,type-punning具有別名問題:使用聯合。 – ams

0

爲什麼需要自行打包緩衝區有什麼特別的理由嗎?在MPI操作之前,你真的實際上壓縮了連續緩衝區中的數據嗎?如果是這樣,你的壓縮和傳輸時間必須低於簡單的傳輸。如果是這樣的話,那麼我可以看到這是很好的理由。

如果你實際上打包在一個連續的緩衝區中,僅用於MPI操作,那麼更好的解決辦法是自己停止打包數據,而是使用MPI派生的數據類型

您可以使用類似「MPI派生數據類型示例」的方式進行網絡搜索,並獲得比我可以在此處簡單寫的更好的解釋。

+0

問題是結構包含的東西不是數據,而是索引到我想發送的一堆值中。所以有點像指針。直接發送這些東西將毫無意義,就像發送指針一樣,所以我需要以某種方式對其進行「解除引用」。僅使用派生數據類型機械來完成,這是某處棘手和不可能之間,因爲此堆棧上的每個值的位移是不相對於包含其索引該結構的開始恆定。 –