GCC: Apa perbedaan Maret dengan mtune?

88

Saya mencoba menghapus halaman manual GCC untuk ini, tetapi masih tidak mengerti, sungguh.

Apa perbedaan antara -marchdan -mtune?

Kapan seseorang menggunakan adil -marchvs. keduanya? Apakah mungkin untuk adil -mtune?

Jameson
sumber

Jawaban:

97

Jika Anda menggunakan, -marchGCC 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=foomenyiratkan -mtune=fookecuali Anda juga menentukan yang berbeda -mtune. Ini adalah salah satu alasan mengapa menggunakan -marchlebih baik daripada hanya mengaktifkan opsi seperti -mavxtanpa melakukan apa pun tentang penyetelan.

Peringatan: -march=nativepada 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.

James Youngman
sumber
10
Tidak menjawab apakah masuk akal untuk menggunakan keduanya atau apakah mtune redundan saat disetel ke nilai yang sama.
Pavel Šimerda
12
@ PavelŠimerda Secara intuitif, jawabannya tersirat dalam definisi dari 2 fitur. Selain itu, dokumentasi secara eksplisit menyatakan marchimplikasinya mtune. Jadi, jawaban atas keberatan Anda masing-masing adalah tidak dan ya.
underscore_d
Terima kasih telah menjelaskan ini dengan sangat elegan! Anda membuatnya mudah dimengerti.
Rahim Khoja
5
Orang membutuhkan tl; dr: Gunakan -march jika Anda HANYA menjalankannya di prosesor Anda, gunakan -mtune jika Anda ingin aman untuk prosesor lain.
j riv
3
Pengguna juga harus memahami bahwa kompiler lama (dirilis sebelum beberapa CPU tidak ada) dapat menghasilkan kombinasi mtunedan optimal yang berbeda march. Posting blog ini menjelaskan hal itu dengan yang lain: lemire.me/blog/2018/07/25/…
qneill
53

Ini yang saya cari di Google:

The -march=Xpilihan mengambil nama CPU Xdan 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=Xakan 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=Ypilihan lagu-lagu kode yang dihasilkan untuk berjalan lebih cepat pada Ydari pada CPU lain mungkin berjalan di. -march=Xmenyiratkan -mtune=X. -mtune=Ytidak akan menimpa -march=X, jadi, misalnya, mungkin tidak masuk akal untuk -march=core2dan -mtune=i686- kode Anda tidak akan berjalan pada apa pun yang lebih lama dari core2bagaimanapun, karena -march=core2, jadi mengapa di Earth Anda ingin mengoptimalkan sesuatu yang lebih tua (kurang berfitur) daripada core2? -march=core2 -mtune=haswelllebih masuk akal: jangan gunakan fitur apa pun di luar yang core2disediakan (yang masih lebih banyak dari yang -march=i686Anda berikan!), tetapi optimalkan kode untuk haswellCPU yang jauh lebih baru , bukan untuk core2.

Ada juga -mtune=generic. genericmembuat GCC menghasilkan kode yang berjalan paling baik pada CPU saat ini (artinya genericperubahan dari satu versi GCC ke versi lainnya). Ada rumor di forum Gentoo yang -march=X -mtune=genericmenghasilkan kode yang berjalan lebih cepat Xdaripada kode yang diproduksi oleh -march=X -mtune=X(atau -march=Xseperti -mtune=Xyang 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=genericada 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.

LRN
sumber
4
Tetapi jika Anda menggunakan -march=native, Anda mungkin ingin menentukan -mtune=X, karena defaultnya masih -mtune=generic, seperti yang dibahas di sini: lemire.me/blog/2018/07/25/…
Roland Weber
@RolandWeber: Itu hanya terjadi jika Anda menggunakan GCC yang terlalu tua untuk mengetahui tentang CPU Anda. -march=nativemenyiratkan tune=nativebaik-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.
Peter Cordes
Sungguh payah bahwa GCC tidak dapat melakukan yang lebih baik dari tune=genericpada 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.
Peter Cordes