2015-06-19 15 views
3

訪問結構構件我有傳遞給函數作爲恆定指針的結構中,我的問題是以下:有功能updatedFields的這兩個實施方式之間的差異:由指針

typedef struct 
{ 
    int spec[100]; 
    int spec1[200]; 
    int spec2[200]; 
    int spec3[500]; 
    int spec4[100]; 
    int spec5[700]; 
    float value[100]; 
    char desc[1000]: 
}t_product; 



void updateFields_1(t_product const* context) 
{ 

    int i,buffer[1500]; 
    int * pt_int; 

    pt_int = (int*)context->spec1;  
    for(i = 0; i < 200; i++) 
    { 
     buffer[i] = pt_int[i]; 
    } 

    pt_int = (int*)context->spec3;   
    for(i = 0; i < 500; i++) 
    { 
     buffer[i] = pt_int[i]; 
    } 

    ... 
} 

void updateFields_2(t_product const* context) 
{ 

    int i,buffer[1500]; 

    for(i = 0; i < 200; i++) 
    { 
     buffer[i] = context->spec1[i]; 
    } 

    for(i = 0; i < 500; i++) 
    { 
     buffer[i] = context->spec3[i]; 
    } 

    ... 
} 

int main(void) 
{ 
    t_product prod; 

    /* Initialisation of the structure */ 
    ... 

    updateField(&prod); 

} 

我的意思是,使用指向結構體成員的指針(指向數組的指針)而不是直接訪問結構體的成員是有好處的。

這可能是一個愚蠢的問題,但我不知道結構成員的訪問「花費」更多的操作。

+1

請在'pt_int =(int *)context-> spec3;'中丟失轉換。這些類型已經兼容,免費鑄造可以隱藏錯誤。 –

+0

你確實需要'for'循環嗎?我認爲,對於單個成員(數組類型),你可以直接使用'memcpy()',不是嗎? –

+0

它是* int * main,不是void main。我冒昧地改正它。 – Jens

回答

2

它不會花費更多的在你的情況。即使沒有優化。實際上,如果您未啓用優化,則您的pt_int示例可能會稍微惡化。

這是因爲context->spec3[i]不引用比pt_int[i]更多的指針。 pt_int[i]只是一個指針加上偏移量,所以訪問權限可以寫爲@(ptr_int + 4*i)。在context->spec3[i]中,它可能看起來像還有一個指針被解除引用,但事實並非如此。 spec3不是context中的值,它只是上下文的偏移量。您訪問的地址因此將是@(context + 2000 + 4*i)。只有一個指針訪問。

現在你可以想知道@(context + 2000 + 4*i)的成本是否高於@(ptr_int + 4*i)。事實並非如此,因爲包括x86,AMD64和ARM在內的大多數架構(即100%的個人設備)都有指示以不變的偏移量進行訪問。而且,只要啓用簡單的優化,差異就會消失,因爲context + 2000可以轉換爲單個context_2000(但編譯器實際上不會這樣做,因爲它只會使性能惡化)。

+0

說@ @(context + 2000 + 4 * i)'和@ @(ptr_int + 4 * i)的代價都是一樣的,只是因爲有一個*指令來進行具有常數偏移的訪問* ? – mastov

+0

@mastov是的,因爲這意味着它們對於兩者來說都是相同的指令,並且偏移不會使這些指令更昂貴(偏移對於計算而言是微不足道的)。 – ElderBug

1

它花費更多(它必須在每次迭代時去掉原始指針的引用),但是代價可能很小,並且一個半路體面的編譯器會爲你做這個優化。