[英]Passing struct pointer vs passing struct
我最近寫了很多程序,它們圍繞函數傳遞struct
,以避免全局變量。 但是,我想知道傳遞struct
本身或它的指針是否更有效。 它聽起來應該是這樣,因為指針(在我的64位GNU / Linux系統上)是8個字節,而一個充滿指針的struct
顯然遠不止於此。
但是,如果我有這個struct
:
struct Point {
int x;
int y;
}
這是8個字節,與指針大小相同,是將整個struct
傳遞給函數還是傳遞指針更好? 我非常精通C內存分配,所以在初始化指針時使用malloc
和朋友不是問題。
另一個想法是,如果它們很大,直接傳遞結構會占用大量的堆棧空間。 然而,簡單地使用指針會耗盡內存,可以輕松free
編輯。
[ 這個問題和它的答案對傳遞結構與結構指針的優點和缺點進行了相當徹底的一般處理。 這個答案打算處理這個問題中提到的特定情況,即8字節結構與8字節指針以及在寄存器中傳遞參數的ABI。
在運行Linux的64位Intel CPU上,ABI 要求通過寄存器傳遞8個字節的參數,直到不再剩下。 例如,第一個通過%rdi
寄存器傳遞。 這與優化無關。 這是ABI的要求。
在這種特殊情況下(8字節結構與8字節指針),指針和結構都將通過一個寄存器傳遞。 即兩種情況都不使用堆棧 。 事實上,如果你有一個簡單的功能,如:
int
add (struct Point p)
{
return p.x + p.y;
}
..並使用gcc -O1
編譯,該函數甚至沒有堆棧幀。
您可以在生成的代碼中看到這一點(x86_64 Linux gcc
5.1,帶-O1
):
# Passing the struct:
movq %rdi, %rax
sarq $32, %rax
addl %edi, %eax
ret
# Passing a pointer to the struct:
# [each (%rdi) is a memory access]
movl 4(%rdi), %eax
addl (%rdi), %eax
ret
但正如您所看到的,指針版本訪問內存兩次。 因此, 傳遞值更快 。 傳遞指針將生成內存訪問,以獲取結構的成員。 然后還有一個額外的風險,即結構可能位於未被CPU緩存緩存的內存塊上,並且訪問將導致緩存未命中。 這不應該發生,因為通常,調用者只是訪問了相同的結構,因此它在緩存上。
在32位Linux上, int
繼續為4個字節,但指針變小(8到4)。 並且由於參數在堆棧上傳遞,這意味着傳遞指針會在堆棧上保存4個字節(8字節結構,而不是4字節指針)。 但我仍然喜歡通過改變空間局部性來傳遞價值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.