Saya mencoba menghapus halaman manual GCC untuk ini, tetapi masih tidak mengerti, sungguh.
Apa perbedaan antara -march
dan -mtune
?
Kapan seseorang menggunakan adil -march
vs. keduanya? Apakah mungkin untuk adil -mtune
?
Jawaban:
Jika Anda menggunakan, -march
GCC akan bebas membuat instruksi yang bekerja pada CPU yang ditentukan, tetapi (biasanya) tidak pada CPU sebelumnya dalam keluarga arsitektur.
Jika Anda hanya menggunakan -mtune
, maka compiler akan menghasilkan kode yang berfungsi pada salah satu darinya, tetapi akan mendukung urutan instruksi yang berjalan paling cepat pada CPU tertentu yang Anda tunjukkan. misalnya menyetel heuristik loop-unrolling secara tepat untuk CPU tersebut.
-march=foo
menyiratkan -mtune=foo
kecuali Anda juga menentukan yang berbeda -mtune
. Ini adalah salah satu alasan mengapa menggunakan -march
lebih baik daripada hanya mengaktifkan opsi seperti -mavx
tanpa melakukan apa pun tentang penyetelan.
Peringatan: -march=native
pada CPU yang tidak dikenali GCC secara khusus akan tetap mengaktifkan set instruksi baru yang dapat dideteksi oleh GCC, tetapi akan keluar -mtune=generic
. Gunakan GCC baru yang cukup baru yang mengetahui tentang CPU Anda jika Anda ingin membuat kode yang baik.
march
implikasinya mtune
. Jadi, jawaban atas keberatan Anda masing-masing adalah tidak dan ya.
mtune
dan optimal yang berbeda march
. Posting blog ini menjelaskan hal itu dengan yang lain: lemire.me/blog/2018/07/25/…
Ini yang saya cari di Google:
The -march=X
pilihan mengambil nama CPU X
dan memungkinkan GCC untuk menghasilkan kode yang menggunakan semua fitur X
. Manual GCC menjelaskan dengan tepat nama CPU mana yang berarti keluarga dan fitur CPU mana.
Karena fitur biasanya ditambahkan, tetapi tidak dihapus, biner yang dibangun dengan -march=X
akan berjalan pada CPU X
, memiliki peluang bagus untuk berjalan pada CPU yang lebih baru dari X
, tetapi hampir pasti tidak akan berjalan pada yang lebih tua dari X
. Set instruksi tertentu (3DNow !, i guess?) Mungkin khusus untuk vendor CPU tertentu, memanfaatkan ini mungkin akan membuat Anda mendapatkan binari yang tidak berjalan pada CPU yang bersaing, yang lebih baru atau sebaliknya.
The -mtune=Y
pilihan lagu-lagu kode yang dihasilkan untuk berjalan lebih cepat pada Y
dari pada CPU lain mungkin berjalan di. -march=X
menyiratkan -mtune=X
. -mtune=Y
tidak akan menimpa -march=X
, jadi, misalnya, mungkin tidak masuk akal untuk -march=core2
dan -mtune=i686
- kode Anda tidak akan berjalan pada apa pun yang lebih lama dari core2
bagaimanapun, karena -march=core2
, jadi mengapa di Earth Anda ingin mengoptimalkan sesuatu yang lebih tua (kurang berfitur) daripada core2? -march=core2 -mtune=haswell
lebih masuk akal: jangan gunakan fitur apa pun di luar yang core2
disediakan (yang masih lebih banyak dari yang -march=i686
Anda berikan!), tetapi optimalkan kode untuk haswell
CPU yang jauh lebih baru , bukan untuk core2
.
Ada juga -mtune=generic
. generic
membuat GCC menghasilkan kode yang berjalan paling baik pada CPU saat ini (artinya generic
perubahan dari satu versi GCC ke versi lainnya). Ada rumor di forum Gentoo yang -march=X -mtune=generic
menghasilkan kode yang berjalan lebih cepat X
daripada kode yang diproduksi oleh -march=X -mtune=X
(atau -march=X
seperti -mtune=X
yang tersirat). Tidak tahu apakah ini benar atau tidak.
Umumnya, kecuali Anda tahu persis apa yang Anda butuhkan, tampaknya kursus terbaik adalah menentukan -march=<oldest CPU you want to run on>
dan -mtune=generic
( -mtune=generic
ada di sini untuk melawan implisit -mtune=<oldest CPU you want to run on>
, karena Anda mungkin tidak ingin mengoptimalkan untuk CPU yang paling lama). Atau hanya -march=native
, jika Anda hanya akan berjalan di mesin yang sama dengan yang Anda buat.
-march=native
, Anda mungkin ingin menentukan -mtune=X
, karena defaultnya masih -mtune=generic
, seperti yang dibahas di sini: lemire.me/blog/2018/07/25/…
-march=native
menyiratkan tune=native
baik-baik saja jika Anda menggunakan GCC yang mengetahui tentang CPU Anda. Artikel itu hanya menyajikan kasus buruk. Versi GCC yang lebih baru membuat kode yang lebih baik secara umum, terutama saat menggunakan instruksi baru seperti AVX2 dan AVX-512. Dan memiliki pengaturan tuning (seperti loop unroll heuristics) yang dirancang untuk CPU Anda adalah nilai tambah yang pasti. Jadi jika Anda cukup peduli dengan kinerja untuk menggunakan opsi ini, gunakan GCC baru, setidaknya yang tahu tentang CPU Anda, sebaiknya relese stabil saat ini.
tune=generic
pada anggota baru dari keluarga mikroarsitektur yang sama, terutama sesuatu seperti Kaby Lake yang secara harfiah identik dengan mikroarsitektur Skylake. Tapi saya pikir itu masih memiliki keluarga / langkah yang berbeda sehingga GCC yang hanya tahu tentang Skylake dan yang lebih tua bisa gagal mengenalinya untuk penyetelan.