Làm thế nào để xem cờ nào -march = bản địa sẽ kích hoạt?


165

Tôi đang biên dịch ứng dụng C ++ của mình bằng GCC 4.3. Thay vì chọn thủ công các cờ tối ưu hóa mà tôi đang sử dụng -march=native, theo lý thuyết nên thêm tất cả các cờ tối ưu hóa áp dụng cho phần cứng tôi đang biên dịch. Nhưng làm thế nào tôi có thể kiểm tra những lá cờ nào thực sự sử dụng?

Câu trả lời:


150

Bạn có thể sử dụng các -Q --help=targettùy chọn:

gcc -march=native -Q --help=target ...

Các -vtùy chọn cũng có thể được sử dụng.

Bạn có thể xem tài liệu về --helptùy chọn ở đây .


10
Tôi sẽ đề nghị rằng điều này là tối ưu. Đầu ra của --help = target không hiển thị thông tin bộ đệm CPU, trong đó các phương thức cả elias và 42n4 dưới đây đã được liệt kê. Cụ thể, trên gcc 4.9.2 trên Phenom, đầu ra bao gồm:--param l1-cache-size=64 --param l1-cache-line-size=64 --param l2-cache-size=512
Daniel Santos

@DanielSantos: trên hệ thống của tôi, nó hiển thị các tham số đó với -vtùy chọn, mặc dù là một phần của cc1dòng lệnh ...
thkala

không hoàn hảo. trên gcc phiên bản 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-bẩn) nó sẽ gây ra lỗi khi trả về: Thông báo trình biên dịch mã: Lỗi: kiến ​​trúc không xác định Lỗi: không nhận dạng tùy chọn -march = tự nhiên. Vì vậy, mất -march=nativevà nó sẽ hoạt động ở khắp mọi nơi chỉ sau : gcc -Q --help=target.
Oleg Kokorin

@Oleg - Đó là âm thanh như một lỗi trong GCC 5. Vấn đề là không có mặt trong GCC 7.
jww

111

Để xem cờ dòng lệnh, sử dụng:

gcc -march=native -E -v - </dev/null 2>&1 | grep cc1

Nếu bạn muốn xem trình biên dịch / trình biên dịch trước định nghĩa được đặt theo các tham số nhất định, hãy làm điều này:

echo | gcc -dM -E - -march=native

1
Câu trả lời này xứng đáng được nhiều người ủng hộ như người được chấp nhận, đặc biệt, liệt kê những gì nativethực sự tương đương.
Idillotexist Idillotexist

4
Vì vậy, nếu tôi muốn biên dịch chéo, tôi nên cung cấp cho cả trình biên dịch cả hai định nghĩa AND các đối số? hoặc là đủ các đối số?
hanshenrik

25

Nó sẽ là ( -###tương tự như -v):

echo | gcc -### -E - -march=native 

Để hiển thị các cờ gốc "thực" cho gcc.

Bạn có thể làm cho chúng xuất hiện "rõ ràng" hơn bằng một lệnh:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )//g'

và bạn có thể thoát khỏi cờ với -mno- * với:

gcc -### -E - -march=native 2>&1 | sed -r '/cc1/!d;s/(")|(^.* - )|( -mno-[^\ ]+)//g'

10

Nếu bạn muốn tìm hiểu cách thiết lập một trình biên dịch chéo không bản địa, tôi thấy điều này hữu ích:

Trên máy mục tiêu,

% gcc -march=native -Q --help=target | grep march
-march=                               core-avx-i

Sau đó sử dụng cái này trên máy dựng:

% gcc -march=core-avx-i ...

Điều này sẽ không bao gồm tất cả các cờ không may.
Baptiste Wicht

@BaptisteWicht có những lá cờ mà -march = bản địa sẽ bao gồm -march = core-avx-i sẽ không, trong trường hợp này, hay những lá cờ nào? Cảm ơn!
rogerdpack

2
@rogerdpack Trên máy tính này (sandbridge), march = sandbridge không kích hoạt AVX (không biết tại sao) trong khi march = bản địa thì không. Một sự khác biệt quan trọng khác là kích thước bộ đệm chỉ được trích xuất với march = bản địa
Baptiste Wicht

1
@BaptisteWicht có vẻ kỳ quặc hoạt động ở đây (tôi đoán vậy): echo | gcc-6 -dM -E - -march=sandybridge | grep AVX #define __AVX__ 1nhưng kích thước bộ đệm dường như không có.
rogerdpack

7

Tôi sẽ ném hai xu của mình vào câu hỏi này và đề nghị một phần mở rộng dài hơn một chút cho câu trả lời của elias. Kể từ gcc 4.6, việc chạy gcc -march=native -v -E - < /dev/nullphát ra lượng thư rác ngày càng tăng dưới dạng -mno-*cờ thừa . Sau đây sẽ loại bỏ những điều này:

gcc -march=native -v -E - < /dev/null 2>&1 | grep cc1 | perl -pe 's/ -mno-\S+//g; s/^.* - //g;'

Tuy nhiên, tôi chỉ xác minh tính chính xác của điều này trên hai CPU khác nhau (Intel Core2 và AMD Phenom), vì vậy tôi cũng khuyên bạn nên chạy đoạn script sau để chắc chắn rằng tất cả các -mno-*cờ này có thể được gỡ bỏ an toàn.

#!/bin/bash

gcc_cmd="gcc"

# Optionally supply path to gcc as first argument
if (($#)); then
    gcc_cmd="$1"
fi

with_mno=$(
    "${gcc_cmd}" -march=native -mtune=native -v -E - < /dev/null 2>&1 |
    grep cc1 |
    perl -pe 's/^.* - //g;'
)
without_mno=$(echo "${with_mno}" | perl -pe 's/ -mno-\S+//g;')

"${gcc_cmd}" ${with_mno}    -dM -E - < /dev/null > /tmp/gcctest.a.$$
"${gcc_cmd}" ${without_mno} -dM -E - < /dev/null > /tmp/gcctest.b.$$

if diff -u /tmp/gcctest.{a,b}.$$; then
    echo "Safe to strip -mno-* options."
else
    echo
    echo "WARNING! Some -mno-* options are needed!"
    exit 1
fi

rm /tmp/gcctest.{a,b}.$$

Tôi không tìm thấy sự khác biệt giữa gcc -march=native -v -E - < /dev/nullgcc -march=native -### -E - < /dev/nullngoài một số tham số được trích dẫn - và các tham số không chứa ký tự đặc biệt, vì vậy tôi không chắc trong trường hợp nào điều này tạo ra sự khác biệt thực sự.

Cuối cùng, lưu ý rằng --march=nativeđã được giới thiệu trong gcc 4.2, trước đó nó chỉ là một đối số không được công nhận.


Thật tuyệt, gleans này cũng có kích thước bộ đệm
rogerdpack

gcc phiên bản 5.4.0 (Buildroot 2017.05-rc2-00016-gc7eaf50-bẩn) trả về: Lỗi: kiến ​​trúc không xác định 'bản địa'
Oleg Kokorin

Oleg: Bạn đang sử dụng vòm nào? Có thể là "bản địa" chỉ được hỗ trợ trên một số kiến ​​trúc.
Daniel Santos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.