簡體   English   中英

使用gcc沒有小的字符串優化?

[英]No small string optimization with gcc?

大多數std::string實現(包括GCC)使用小字符串優化。 例如,有一個答案在討論這個問題。

今天,我決定檢查我編譯的代碼中的字符串在什么時候被移動到堆中。 令我驚訝的是,我的測試代碼似乎表明根本沒有發生小的字符串優化!

碼:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

int main(int argc, char* argv[]) {
  std::string s;

  cout << "capacity: " << s.capacity() << endl;

  cout << (void*)s.c_str() << " | " << s << endl;
  for (int i=0; i<33; ++i) {
    s += 'a';
    cout << (void*)s.c_str() << " | " << s << endl;
  }

}

g++ test.cc && ./a.out的輸出是

capacity: 0
0x7fe405f6afb8 | 
0x7b0c38 | a
0x7b0c68 | aa
0x7b0c38 | aaa
0x7b0c38 | aaaa
0x7b0c68 | aaaaa
0x7b0c68 | aaaaaa
0x7b0c68 | aaaaaaa
0x7b0c68 | aaaaaaaa
0x7b0c98 | aaaaaaaaa
0x7b0c98 | aaaaaaaaaa
0x7b0c98 | aaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0d28 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

我猜測較大的第一個指針,即0x7fe405f6afb8是一個堆棧指針,其他指針指向堆。 多次運行會產生相同的結果,因為第一個地址總是很大,而其他地址都比較小; 確切的值通常不同。 較小的地址始終遵循2分配方案的標准功率,例如0x7b0c38列出一次,然后0x7b0c68列出一次,然后0x7b0c38列出兩次,然后0x7b0c68 4次,然后0x7b0c98 8次,等等。

在閱讀霍華德的答案后,使用64位機器,我希望看到前22個字符打印的地址相同,然后才能看到它發生變化。

我錯過了什么嗎?

另外,有趣的是,如果我使用-O (在任何級別)編譯,我在第一種情況下獲得一個常量小指針值0x6021f8 ,而不是大值,並且無論我運行多少次,這個0x6021f8都不會改變程序。

輸出g++ -v

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/foo/bar/gcc-6.2.0/gcc/libexec/gcc/x86_64-redhat-linux/6.2.0/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../gcc-6.2.0/configure --prefix=/foo/bar/gcc-6.2.0/gcc --build=x86_64-redhat-linux --disable-multilib --enable-languages=c,c++,fortran --with-default-libstdcxx-abi=gcc4-compatible --enable-bootstrap --enable-threads=posix --with-long-double-128 --enable-long-long --enable-lto --enable-__cxa_atexit --enable-gnu-unique-object --with-system-zlib --enable-gold
Thread model: posix
gcc version 6.2.0 (GCC)

你的一面旗幟是:

--with-default-libstdcxx-abi=gcc4-compatible

和GCC4 支持小串optimzation。


GCC5開始支持它。 isocpp說:

默認情況下,使用小字符串優化而不是寫入時復制引用計數來啟用std :: string的新實現。

這支持我的主張。

此外, 探索std :: string提到:

正如我們所見,較舊的libstdc ++實現了寫時復制,因此它們不利用小對象優化是有意義的。

當GCC5進場時,他會改變背景。

暫無
暫無

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

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