2015-10-07 14 views
6

以下兩段是從N4140複製的(重點是我的)。我想我可以理解N4140中的§5.3.4/ 11,但擴展的分配函數的概念對我來說是難以理解的

§5.3.4/ 11:

新表達調用的分配功能和 分配具有被擴展,所述新表達經過 請求分配函數的空間量爲std::size_t類型的第一個 參數。該論據應不小於正在創建的對象的大小 ;它可能大於僅在對象是數組時才創建的對象的大小 。對於charunsigned char 陣列中,新表達的 結果和由 分配函數返回的地址之間的差應是任何對象類型,其最嚴格的 基本對齊要求(3.11)的整數倍大小 不大於正在創建的數組的大小。因爲分配函數被假定爲返回指向存儲器 的指針,該指針適合於具有基本對齊的任何類型的對象,所以這種陣列分配開銷的約束允許分配字符數組的其他對象的其他對象的通用慣用法,其中 其他對象類型將在稍後放置。末端音符]

§5.4.3/ 12

新表達調用的分配功能和 分配被擴展,尺寸參數傳遞給 分配呼叫不得大於 指定的上述呼叫的大小加上擴展的大小 如果呼叫未被擴展,則必須加上任何填充y將對齊分配的內存中的 分配的對象。

我可以理解§5.3.4/ 11,但是其已被擴展的分配功能的概念是難以理解的我,如上面§5.4.3/ 12所列。

+1

這基本上意味着,如果符合/ 12中提到的條件,編譯器可以一次分配'sizeof(class)* 1000'而不是分配'sizeof(class)'1000次。 – SingerOfTheFall

回答

6

這種語言是由N3664: Clarifying Memory Allocation添加的,當分配不是可觀察行爲的一部分時,它允許實現融合分配。換句話說,分配可以是擴展

函數調用本身不延伸,但該函數調用,因此分配可以省略分配可一起在後面作集總到更大的分配。

該提案指出的問題(重點煤礦):

嚴格當前的C和C++標準的閱讀可能會導致一個 得出結論,分配策略將不考慮任何 信息不可導從新的序列中刪除 表達式。實質上,這些標準可能會排除分配的宏觀優化 。

在另一方面,該標準的嚴格讀數可能導致人們 得出結論:實現必須爲每個分配函數調用 和每一個新的表達。此讀數可能不包括 微配優化。

,並提出:

我們建議用措辭更精確 專注於基本要求,以取代現有的機械措辭。 其目的是啓用 的行爲,一些現有的編譯器和內存分配器已經 有。例如,看到TCMalloc

,並進一步說:

上實現一個基本要求是,他們提供 可用內存,不是他們有分配 調用的特定序列。我們建議放寬與新的 表達式有關的撥款電話。

  1. 在某些限制條件下,分配調用的數量不是程序的可觀察行爲的一部分。這個使得 實現可以通過避免 或將它們融合來減少分配調用的數量。

  2. 當避免或融合分配時,所請求的空間量不會超過新表達式所暗含的空間量,其中 例外的填充滿足對齊約束。這 意味着分配的空間量不會增加分配的峯值 。

因爲C++類特定的內存分配往往是調整到 具體的班級規模,我們沒有這樣的放鬆適用於那些 分配器。

這可能會導致分配被完全省略,這在某些情況下可能會令人驚訝。我們可以看到從this question採取了以下例子:

#include <new> 

int main() 
{ 
    int* mem = new (std::nothrow) int[100]; 
    return 0; 
} 

鐺優化這(see it live via godbolt):

main:         # @main 
    xorl %eax, %eax 
    retq 

這是允許的,因爲沒有可觀察的行爲影響,所以這屬於下as-if rule的傘。

+1

我仍然無法看到您的示例中的優化和§5.4.3/ 12 – Belloc

+1

@Belloc之間的關係,它解釋了優化是相當複雜[我的問題鏈接回答](http://stackoverflow.com/a/31877074/1708801)解釋了允許它的邏輯。它基本上歸結爲* as-if規則*。一旦我們被允許省略分配調用,是否允許優化歸結爲它是否會影響可觀察行爲。 –