Saya telah bekerja di bawah prinsip share-nothing pemrograman bersamaan. Pada dasarnya, semua utas pekerja saya memiliki salinan read-only dari negara yang sama yang tidak pernah dibagi di antara mereka ( bahkan dengan referensi ). Secara umum, ini telah bekerja dengan sangat baik.
Sekarang, seseorang telah memperkenalkan cache singleton tanpa kunci ( mis. Kamus statis ) yang diakses semua utas secara bersamaan. Karena kamus tidak pernah diubah setelah startup tidak ada kunci. Belum ada masalah Thread-Safety, tapi sekarang ada penurunan kinerja.
Pertanyaannya adalah ... karena tidak ada kunci mengapa pengenalan singleton ini membuat hit kinerja? Apa sebenarnya yang terjadi di balik selimut yang bisa menjelaskan hal ini?
Untuk mengonfirmasi, mengakses singleton baru ini adalah satu-satunya perubahan dan saya dapat dengan andal menciptakan ini hanya dengan mengomentari panggilan ke cache.
sumber
Jawaban:
Bisa jadi keadaan tidak berubah berbagi cache-line dengan sesuatu yang bisa berubah. Dalam kasus ini, perubahan ke keadaan yang bisa ditransmisikan di dekatnya mungkin memiliki efek memaksa sinkronisasi ulang garis cache ini di seluruh core, yang dapat memperlambat kinerja.
sumber
false sharing
skenario yang Anda gambarkan. Untuk mengisolasinya saya perlu profil L2 Cache. Sayangnya, ini adalah tipe referensi sehingga menambahkan ruang buffer tidak akan menjadi pilihan jika ini yang sebenarnya terjadi.Saya akan memastikan bahwa
Equals()
danGetHashCode()
metode objek yang Anda gunakan sebagai kunci kamus tidak memiliki efek samping yang tidak ramah threading yang tidak terduga. Profiling akan sangat membantu di sini.Jika kebetulan kunci Anda adalah string, maka mungkin di sana Anda memilikinya: desas-desus mengatakan bahwa string berperilaku seperti objek abadi tetapi demi optimasi tertentu mereka secara internal diimplementasikan dalam cara yang bisa berubah, dengan segala sesuatu yang diperlukan sehubungan dengan multithreading .
Saya akan mencoba meneruskan kamus ke utas yang menggunakannya sebagai referensi reguler dan bukan singleton untuk melihat apakah masalahnya terletak pada kebersamaan atau dengan singletonness kamus. (Menghilangkan kemungkinan penyebabnya.)
Saya juga akan mencoba dengan
ConcurrentDictionary
bukannya biasaDictionary
kalau-kalau penggunaannya menghasilkan beberapa hasil yang mengejutkan. Ada banyak hal yang dapat dispekulasikan tentang masalah yang dihadapi jikaConcurrentDictionary
ternyata kinerjanya jauh lebih baik atau lebih buruk daripada yang biasa Anda lakukanDictionary
.Jika tidak ada satu pun dari masalah di atas yang menunjukkan masalah, maka saya akan menebak bahwa kinerja terdegradasi disebabkan oleh semacam pertikaian aneh antara benang pengumpul sampah dan sisa benang Anda, karena pengumpul sampah berusaha mencari tahu apakah objek dalam kamus Anda harus dibuang atau tidak, saat sedang diakses oleh utas Anda.
sumber