Berapa biaya operasi atom (salah satu dari perbandingan-dan-tukar atau penambahan / pengurangan atom)? Berapa siklus yang dikonsumsi? Apakah akan menjeda prosesor lain di SMP atau NUMA, atau akan memblokir akses memori? Apakah itu akan membersihkan buffer pemesanan ulang di CPU yang rusak?
Efek apa yang akan terjadi pada cache?
Saya tertarik dengan CPU modern dan populer: x86, x86_64, PowerPC, SPARC, Itanium.
Jawaban:
Saya telah mencari data aktual selama beberapa hari terakhir, dan tidak menemukan apa pun. Namun, saya melakukan beberapa penelitian, yang membandingkan biaya operasi atom dengan biaya kehilangan cache.
Biaya awalan x86 LOCK, (termasuk
lock cmpxchg
untuk CAS atom), sebelum PentiumPro (seperti yang dijelaskan dalam dokumen), adalah akses memori (seperti cache miss), + menghentikan operasi memori oleh prosesor lain, + perselisihan apa pun dengan prosesor lain mencoba MENGUNCI bus. Namun, sejak PentiumPro, untuk memori Writeback normal yang dapat di-cache (semua memori yang ditangani aplikasi, kecuali Anda berbicara langsung dengan perangkat keras), alih-alih memblokir semua operasi memori, hanya baris cache yang relevan yang diblokir (berdasarkan tautan dalam jawaban @ osgx ) .yaitu penundaan inti menjawab bagian MESI dan permintaan RFO untuk saluran tersebut sampai setelah bagian penyimpanan dari
lock
operasi ed yang sebenarnya . Ini disebut "kunci cache", dan hanya mempengaruhi satu baris cache itu. Core lain dapat memuat / menyimpan atau bahkan meng-CAS saluran lain pada saat yang bersamaan.Sebenarnya, kasus CAS bisa menjadi lebih rumit, seperti yang dijelaskan di halaman ini , tanpa pengaturan waktu tetapi dengan deskripsi yang mendalam oleh teknisi yang dapat dipercaya. (Setidaknya untuk kasus penggunaan normal di mana Anda melakukan pemuatan murni sebelum CAS yang sebenarnya.)
Sebelum membahas terlalu banyak detail, saya akan mengatakan bahwa operasi TERKUNCI menghabiskan satu cache yang hilang + kemungkinan pertikaian dengan prosesor lain pada cacheline yang sama, sementara CAS + beban sebelumnya (yang hampir selalu diperlukan kecuali pada mutex, di mana Anda selalu CAS 0 dan 1) dapat menyebabkan kehilangan dua cache.
Dia menjelaskan bahwa beban + CAS di satu lokasi sebenarnya dapat menyebabkan kehilangan dua cache, seperti Load-Linked / Store-Conditional (lihat di sana untuk yang terakhir). Penjelasannya bergantung pada pengetahuan tentang protokol koherensi cache MESI . Ini menggunakan 4 status untuk cacheline: M (odified), E (xclusive), S (hared), I (nvalid) (dan oleh karena itu disebut MESI), dijelaskan di bawah jika diperlukan. Skenario tersebut, dijelaskan, adalah sebagai berikut:
Dalam semua kasus, permintaan cacheline dapat dihentikan oleh pemroses lain yang sudah memodifikasi data.
sumber
Saya melakukan beberapa profil dengan pengaturan berikut: Mesin uji (AMD Athlon64 x2 3800+) di-boot, dialihkan ke mode panjang (interupsi dinonaktifkan) dan instruksi yang diinginkan dijalankan dalam satu lingkaran, 100 iterasi dibuka gulungan dan 1.000 siklus loop. Badan loop disejajarkan dengan 16 byte. Waktu diukur dengan instruksi rdtsc sebelum dan sesudah loop. Selain itu, sebuah dummy loop tanpa instruksi apa pun dijalankan (yang mengukur 2 siklus per iterasi loop dan 14 siklus untuk sisanya) dan hasilnya dikurangi dari hasil waktu pembuatan profil instruksi.
Instruksi berikut diukur:
lock cmpxchg [rsp - 8], rdx
" (keduanya cocok perbandingan dan tidak cocok),lock xadd [rsp - 8], rdx
",lock bts qword ptr [rsp - 8], 1
"Dalam semua kasus, waktu yang diukur adalah sekitar 310 siklus, kesalahannya sekitar +/- 8 siklus
Ini adalah nilai untuk eksekusi berulang pada memori (cache) yang sama. Dengan cache tambahan yang hilang, waktunya jauh lebih tinggi. Ini juga dilakukan dengan hanya satu dari 2 inti yang aktif, jadi cache dimiliki secara eksklusif, dan tidak diperlukan sinkronisasi cache.
Untuk mengevaluasi biaya instruksi terkunci pada cache miss, saya menambahkan
wbinvld
instruksi sebelum instruksi terkunci dan menambahkanwbinvld
plus anadd [rsp - 8], rax
ke dalam loop perbandingan. Dalam kedua kasus biayanya sekitar 80.000 siklus per pasangan instruksi! Dalam kasus bts kunci perbedaan waktu sekitar 180 siklus per instruksi.Perhatikan bahwa ini adalah throughput timbal balik, tetapi karena operasi yang dikunci adalah operasi serialisasi, mungkin tidak ada perbedaan pada latensi.
Kesimpulan: operasi terkunci itu berat, tapi cache miss bisa jauh lebih berat. Juga: operasi yang terkunci tidak menyebabkan kehilangan cache. Ini hanya dapat menyebabkan lalu lintas sinkronisasi cache, jika cache tidak dimiliki secara eksklusif.
Untuk mem-boot mesin, saya menggunakan FreeLdr versi x64 dari proyek ReactOS. Berikut kode sumber asm:
sumber
Pada SMP berbasis bus, prefiks atomik
LOCK
menegaskan (menghidupkan) sinyal kabel busLOCK#
. Ini akan melarang cpus / perangkat lain di bus untuk menggunakannya.Buku Ppro & P2 http://books.google.com/books?id=3gDmyIYvFH4C&pg=PA245&dq=lock+instruction+pentium&lr=&ei=_E61S5ehLI78zQSzrqwI&cd=1#v=onepage&q=lock%20instruction%20pentium&f=46 halaman palsu
sumber