2017-09-06 23 views
10

Hầu hết các triển khai std::string (bao gồm GCC) sử dụng tối ưu hóa chuỗi nhỏ. Ví dụ. có một số answer thảo luận về điều này.Không tối ưu hóa chuỗi nhỏ với gcc?

Hôm nay, tôi quyết định kiểm tra xem một chuỗi trong mã tôi biên dịch được chuyển đến vùng nào. Trước sự ngạc nhiên của tôi, mã thử nghiệm của tôi dường như cho thấy không có tối ưu hóa chuỗi nhỏ nào xảy ra!

Code:

#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; 
    } 

} 

Kết quả của 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 

Tôi đoán rằng con trỏ đầu tiên lớn hơn, tức là 0x7fe405f6afb8 là một con trỏ ngăn xếp, và những người khác trỏ đến đống . Chạy nhiều lần này tạo ra kết quả giống hệt nhau, theo nghĩa là địa chỉ đầu tiên luôn lớn, và các địa chỉ còn lại nhỏ hơn; các giá trị chính xác thường khác nhau. Các địa chỉ nhỏ hơn luôn tuân theo sức mạnh chuẩn của 2 lược đồ phân bổ, ví dụ: 0x7b0c38 được liệt kê một lần, sau đó 0x7b0c68 được liệt kê một lần, sau đó 0x7b0c38 hai lần, sau đó 0x7b0c68 4 lần, sau đó 0x7b0c98 8 lần, vv

Sau khi đọc câu trả lời Howard, sử dụng một máy 64bit, tôi đã mong đợi để xem cùng một địa chỉ in cho 22 ký tự đầu tiên, và chỉ sau đó mới thấy nó thay đổi.

Tôi có thiếu gì đó không?

Ngoài ra, thú vị, nếu tôi biên dịch với -O (ở bất kỳ cấp độ), tôi nhận được một hằng số nhỏ giá trị con trỏ 0x6021f8 trong trường hợp đầu tiên, thay vì giá trị lớn, và 0x6021f8 này không thay đổi bất kể bao nhiêu lần Tôi chạy chương trình.

Sản lượng 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) 
+1

'--with-default-libstdcxx-abi = gcc4 tương thích' –

+0

@ T.C. Có thật không? 'gcc4' không có tối ưu hóa chuỗi nhỏ? – SU3

+0

Tôi nghĩ rằng tôi nhớ rằng tối ưu hóa chuỗi nhỏ đã được đưa (trở lại) vào ngôn ngữ – xaxxon

Trả lời

13

Một trong những lá cờ của bạn là:

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

và GCC4 không không hỗ trợ chuỗi nhỏ Optimzation.


GCC5 bắt đầu hỗ trợ. isocpp tiểu bang:

Triển khai mới chuỗi std :: được bật theo mặc định, sử dụng tính năng tối ưu hóa chuỗi nhỏ thay vì đếm tham chiếu sao chép.

hỗ trợ khiếu nại của tôi.

Hơn nữa, Exploring std::string đề cập:

Như chúng ta thấy, cũ libstdC++ cụ sao chép-on-viết, và vì vậy nó làm cho ý nghĩa đối với họ không sử dụng đối tượng nhỏ tối ưu hóa.

và sau đó anh ấy thay đổi ngữ cảnh, khi GCC5 phát huy tác dụng.