簡體   English   中英

使用-O3選項優化結構指針

[英]struct pointer being optimized out using -O3 option

調試優化的代碼似乎是不可能的。 我花了太長時間試圖超越編譯器。 由於編譯器優化了我的代碼,我很難做一個簡單的檢查我的結構是否為null,不要誤會我的意思,我想保留-O3選項,以加快我的代碼的速度,但是如果由於編譯器的優化,我不斷收到很多錯誤,我可能會關閉它。

我有一個線程,它將嘗試從數組中取出結構條目並將它們放入數據庫中,但是由於某種原因,結構正在被優化。

void *queue_func(void *param){
    LogArgs* largs;
    pthread_mutex_t *mx = (pthread_mutex_t*) param;

    InitQueue();
    while(!needQuit(mx)){
        if((largs = Dequeue()) != NULL){ // the boolean result is true here
            interrupt_log(largs->event, largs->rawtime); // yet largs is NULL here!!!
        }
        usleep(50000);
    }
    return NULL;
}

作為參考,這里是出隊功能和結構:

LogArgs* Dequeue(){
    LogArgs* largs;

    if(isEmpty()) return NULL;
    else{
        largs = &queue[++head % MAX_SIZE];
        return largs;
    }
}

這是結構:

typedef struct {
    time_t *rawtime;
    char event[129];
} LogArgs;

有什么方法可以防止延遲優化嗎?

正如您已經注意到的那樣,進行全面優化的調試只是一種痛苦。 使用volatile等技巧並沒有多大幫助,完全禁用優化可能甚至更快,因為volatile禁止編譯器將變量放入寄存器(例如)。

嘗試-Og (自gcc 4.8起)。 這應該啟用不會干擾調試的優化。

如果兩個線程之間有數據結構, 必須告訴編譯器它們是特殊的。 但是,對於具有高速緩存等的現代多CPU系統, volatile對應用程序層代碼幾乎沒有用。 請改用原子類型( stdatomic.h )-從gcc 4.9開始完全受支持。 其中包括障礙物(又稱柵欄),以確保通道的正確排序。

如果Dequeue()函數是在同一個翻譯單元(粗略地說,同樣.c文件),那么它很可能,它被內聯到queue_func()這樣的代碼queue_func()最終看起來更像這個:

void *queue_func(void *param)
{
    LogArgs* largs;
    pthread_mutex_t *mx = (pthread_mutex_t*) param;

    InitQueue();
    while (!needQuit(mx))
    {
        if (!isEmpty()) // the boolean result is true here
        {
            largs = &queue[++head % MAX_SIZE];
            interrupt_log(largs->event, largs->rawtime); // yet largs is NULL here!!!
        }
        usleep(50000);
    }
    return NULL;
}

...然后,編譯器發現根本沒有必要設置largs ,因為它可以將其轉換為:

void *queue_func(void *param)
{
    LogArgs* largs;
    pthread_mutex_t *mx = (pthread_mutex_t*) param;

    InitQueue();
    while (!needQuit(mx))
    {
        if (!isEmpty()) // the boolean result is true here
        {
            size_t temp_index = ++head % MAX_SIZE;
            interrupt_log(queue[temp_index].event, queue[temp_index].rawtime); // yet largs is NULL here!!!
        }
        usleep(50000);
    }
    return NULL;
}

...現在很明顯,為什么largs可以為largs編譯器根本不用理會它,因為沒有它,代碼也具有相同的效果。

調試優化的代碼可能很困難。 您可以在沒有優化的情況下進行編譯並嘗試重現該問題,或者在調試優化的代碼時檢查機器代碼並在調試器中注冊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM