2015-06-23 10 views
2

我在c中有一個工作函數實現,它需要大量本地分配的內存塊作爲工作空間。在保證所需的工作空間量不會改變的情況下,該函數會被連續調用。爲了優化函數,我重新構造了它在第一次被調用時分配一個靜態單個連續的內存塊,只有當它被要求時纔會釋放它。它看起來是這樣的將c實現的靜態分配的工作區轉換爲C++

void worker(struct* ptr, size_t m) { 
    static double *stack; 
    static size_t sz_stack; 
    static double *alpha; 
    static double *delta; 

    if (!ptr) { 
     if (stack) { 
      free(stack); 
     } 
     stack = NULL; 
     sz_stack = 0; 
     return; 
    } 

    if (!stack) { 
     sz_stack = 2*m; 
     stack = calloc(sz_stack, sizeof(*stack)); 

     if (stack==NULL) 
      // Error and cleanup 
     alpha = stack; 
     delta = alpha + m; 
    } 

    // Do work using alpha and delta as arrays 
    return; 
} 

調用者可以先後調用這個函數,其中ptr將只要通過m給出的問題的規模不會改變持有最終結果。當呼叫者完成該功能或問題大小改變時,他呼叫worker(NULL, 0);,分配的內存將被釋放。

我現在正在改寫這個代碼庫c++和最佳實踐告訴我,我已經使用個人std::vectoralphadelta,而不是連續stack。然而,性能分析表明存在巨大的瓶頸,因爲容器分配和釋放了每個函數調用。現在

我的問題是:

什麼是保持一個連續的一塊在調用之間的函數工作空間的現代c++方式?

+0

如果你不需要手動釋放內存,你可以有一個'static std :: vector'。 –

+0

或者,也許你可以使用一個自定義分配器來保存緩衝區,從而可以快速「分配」內存。 –

回答

2

如果確保在連續函數調用期間所需的工作空間不會發生變化(如您所述),對我來說,最簡單的解決方案似乎是使用靜態數組(有點類似於您的C代碼,但使用'新'和'刪除[]'而不是'calloc'和'free')。

0

靜態是一件可怕的事情,因爲它在線程安全性方面非常糟糕,而且完全沒有必要。

現代化的方法是下列之一:

聲明內存進一步向上堆棧。矢量<>或數組<>或者甚至malloc如果你喜歡。將一個指針(或者等價的參考)傳遞給你的函數。或者,把你的函數寫成一個類的成員。將內存聲明爲您班級的成員。創建類的一個實例,然後重複調用該函數:

struct oo_hack 
{ 
    void worker (struct* ptr, size_t m) 
    { 
    // Do some things using storage 
    } 
    vector<double> storage; 
} 
int main() 
{ 
    oo_hack myhack; // This is on the stack, but has a vector inside 
    while (1) 
    { 
    myhack.worker(0,0); 
    } 
    return 0; 
} // memory gets freed here 

我建議,宣佈進一步的內存在棧上,並把它傳遞到功能,但你可能傾向於第二種。

1

C++的方式是有一個私有數組,然後您可以管理一個類。

在我看來,你處理靜態內存的方式非常類似於構造函數和析構函數。我會將該陣列作爲唯一私人成員,然後將其作爲公共成員函數。另外,在性能方面,STL可以做一些奇怪的事情,每個實現可能比下一個更奇怪或更少奇怪。如果你真的想要速度(如你所見),有時你必須自己處理事情。