Mengapa keadaan bersama menurunkan kinerja?

19

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.

JoeGeeky
sumber
8
Sudahkah Anda mengarahkan profiler ke kode?
Timo Geusch
2
Pembuatan profil tidak mungkin untuk menjawab pertanyaan ini kecuali Anda membuat profil CLR dan mungkin kernel windows (bukan tugas yang mudah untuk programmer biasa).
Igby Largeman
1
@JoeGeeky Alrighty kalau begitu, saya kira satu-satunya yang harus dilakukan untuk saya di sini adalah +1 dan menguntungkan! Tampaknya aneh karena mereka berdua pada tingkat tipuan yang sama, dan harus tetap dalam cache prosesor, dll ...
Max
2
FWIT Saya menelurkan beberapa utas dan menjalankan beberapa timer. Saya instantiated sebuah kelas, singleton, lockedSingleton, dan dict <string, string>. Setelah instantiasi pertama masing-masing, berturut-turut berjalan sekitar 2000ns untuk setiap objek yang diberikan. Kamus berjalan 2x lebih lambat, mungkin disebabkan oleh kode konstruktor ... lebih lambat dari kunci dengan sendirinya. Mempertimbangkan semua GC, penanganan OS dari antrian thread dan overhead lainnya ... tidak yakin orang dapat menjawab pertanyaan ini. Tapi, dari hasil saya, saya tidak percaya masalah ini ada hubungannya dengan Singletons. Tidak jika diterapkan seperti pada MSDN. Tidak termasuk optimisasi kompiler.
P.Brian.Mackey
1
@ JoeGeeky - pemikiran lain: apakah menggunakan cache menambah tingkat tipuan? Jika sering diakses, mengejar pointer ekstra deref (atau MSIL equiv) dapat menambah waktu lebih dari salinan lokal tidak langsung.
sdg

Jawaban:

8

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.

Aidan Cully
sumber
3
Ini terdengar seperti false sharingskenario 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.
JoeGeeky
3

Saya akan memastikan bahwa Equals()dan GetHashCode()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 ConcurrentDictionarybukannya biasa Dictionarykalau-kalau penggunaannya menghasilkan beberapa hasil yang mengejutkan. Ada banyak hal yang dapat dispekulasikan tentang masalah yang dihadapi jika ConcurrentDictionaryternyata kinerjanya jauh lebih baik atau lebih buruk daripada yang biasa Anda lakukan Dictionary.

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.

Mike Nakis
sumber