没有使用gcc进行小的字符串优化? [英] No small string optimization with gcc?

查看:83
本文介绍了没有使用gcc进行小的字符串优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大多数std::string实现(包括GCC)都使用小字符串优化.例如.有一个答案对此进行讨论.

Most std::string implementations (GCC included) use small string optimization. E.g. there's an answer discussing this.

今天,我决定检查我编译的代码中的字符串在什么时候移到堆中.令我惊讶的是,我的测试代码似乎表明根本没有进行任何小的字符串优化!

Today, I decided to check at what point a string in a code I compile gets moved to the heap. To my surprise, my test code seems to show that no small string optimization occurs at all!

代码:

#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次,等等.

I'm guessing that the larger first pointer, i.e. 0x7fe405f6afb8 is a stack pointer, and the other ones point to the heap. Running this many times produces identical results, in the sense that the first address is always large, and the other ones are smaller; the exact values usually differ. The smaller addresses always follow the standard power of 2 allocation scheme, e.g. 0x7b0c38 is listed once, then 0x7b0c68 is listed once, then 0x7b0c38 twice, then 0x7b0c68 4 times, then 0x7b0c98 8 times, etc.

使用64位计算机阅读霍华德的答案后,我期望看到的前22个字符打印的地址相同,然后才看到它的变化.

After reading Howard's answer, using a 64bit machine, I was expecting to see the same address printed for the first 22 characters, and only then to see it change.

我想念什么吗?

此外,有趣的是,如果使用-O进行编译(在任何级别上),在第一种情况下,我都会得到一个恒定的小指针值0x6021f8而不是大值,并且该0x6021f8不会改变不管我运行多少次.

Also, interestingly, if I compile with -O (at any level), I get a constant small pointer value 0x6021f8 in the first case, instead of the large value, and this 0x6021f8 doesn't change regardless of how many times I run the program.

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不支持小字符串优化.

and GCC4 does not support small string optimzation.

GCC5开始支持它. isocpp 指出:

GCC5 started supporting it. isocpp states:

默认情况下,使用小字符串优化而不是写时复制引用计数来启用std :: string的新实现.

A new implementation of std::string is enabled by default, using the small string optimization instead of copy-on-write reference counting.

支持我的主张.

此外,浏览std :: string 时提到:

如我们所见,较旧的libstdc ++实现了写时复制功能,因此它使 他们没有利用小对象优化的感觉.

As we see, older libstdc++ implements copy-on-write, and so it makes sense for them to not utilize small objects optimization.

然后当GCC5出现时,他更改上下文.

and then he changes context, when GCC5 comes in play.

这篇关于没有使用gcc进行小的字符串优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆