Pahami kumpulan benang CLR .Net

Dalam .Net Framework, CLR bertanggung jawab untuk membagikan sumber daya untuk menjalankan aplikasi. Secara khusus, kumpulan utas CLR menentukan kapan utas akan ditambahkan atau diambil. Memahami cara kerjanya akan membantu Anda menentukan cara mengkonfigurasi aplikasi ASP.Net Anda untuk kinerja yang optimal.

Kumpulan thread CLR berisi dua jenis thread — thread pekerja dan port penyelesaian I / O atau thread IOCP. Itu berarti proses pekerja ASP.Net Anda sebenarnya berisi dua kumpulan utas: kumpulan utas pekerja dan kumpulan utas IOCP. Secara alami, kolam-kolam tersebut memiliki tujuan yang berbeda-beda.

Saat Anda menggunakan metode seperti Task.Run,, TaskFactory.StartNewdan ThreadPool.QueueUserWorkItem, waktu proses memanfaatkan thread pekerja untuk diproses. Saat Anda membuat panggilan I / O asinkron di aplikasi Anda, atau aplikasi Anda mengakses sistem file, database, layanan web, dll., Runtime akan menggunakan thread IOCP. Perhatikan juga bahwa setiap domain aplikasi memiliki kumpulan utasnya sendiri.

Mari kita lihat lebih dekat bagaimana utas ini dibuat dan dihapus di .Net Framework. 

Strategi injeksi benang

Kumpulan utas .Net mulai memasukkan utas baru setiap kali jumlah utas sibuk sama dengan jumlah utas minimum yang dikonfigurasi di kumpulan utas. Nilai default dari pengaturan minimum, yang merupakan jumlah minimum  baik  pekerja dan benang IOCP, ditentukan oleh jumlah prosesor di sistem anda. Karenanya, jika sistem Anda memiliki empat inti, Anda akan memiliki empat utas pekerja dan empat utas IOCP secara default. 

Kumpulan utas .Net kemudian menyuntikkan utas pekerja tambahan sesuai permintaan jika utas yang ada digunakan dan masih ada pekerjaan yang harus diselesaikan. Dengan cara yang sama, jika permintaan sumber daya menurun, kumpulan utas akan mulai mengambil utas. 

Menjalankan cuplikan kode berikut akan menampilkan jumlah pemroses logis di sistem Anda dan jumlah minimum pekerja dan utas IOCP yang tersedia.

static void Main (string [] args)

{

    int minimumWorkerThreadCount, minimumIOCThreadCount;

      int logicalProcessorCount = System.Environment.ProcessorCount;

      ThreadPool.GetMinThreads (keluar minimumWorkerThreadCount, keluar minimumIOCThreadCount);

      Console.WriteLine ("Jumlah prosesor:" + logicalProcessorCount);

     Console.WriteLine (“Jumlah minimum utas Pekerja:“ + minimumWorkerThreadCount);

      Console.WriteLine (“Jumlah minimum utas IOCP:“ + minimumIOCThreadCount);

      Console.Read ();

}

Kumpulan utas .Net mengelola utas menggunakan heuristik bawaan. Strategi yang diadopsi termasuk menghindari kelaparan dan algoritma mendaki bukit. Dalam kasus sebelumnya, kumpulan utas .Net terus menambahkan utas pekerja jika tidak ada kemajuan yang terlihat pada item antrian. Dalam kasus terakhir, kumpulan utas .Net mencoba memaksimalkan throughput menggunakan sesedikit mungkin utas.

Kumpulan utas .Net menyuntikkan atau menghapus utas dengan interval 500 milidetik atau saat utas menjadi bebas, mana saja yang lebih dulu. Sekarang, berdasarkan umpan balik yang tersedia untuk runtime, kumpulan utas .Net menghapus utas atau menambahkan utas untuk memaksimalkan throughput. Jika menambahkan utas tidak meningkatkan throughput, itu menghilangkan utas. Ini adalah teknik mendaki bukit CLR yang sedang beraksi.

Sekarang misalkan Anda menjalankan aplikasi ASP.Net di IIS dan server web Anda memiliki total empat CPU. Asumsikan bahwa pada suatu waktu tertentu, ada 24 permintaan untuk diproses. Secara default, runtime akan membuat empat thread, yang akan tersedia untuk melayani empat permintaan pertama. Karena tidak ada utas tambahan yang akan ditambahkan hingga 500 milidetik telah berlalu, 20 permintaan lainnya harus menunggu dalam antrian. Setelah 500 milidetik berlalu, utas baru dibuat.

Seperti yang Anda lihat, dibutuhkan interval 500 md untuk mengejar beban kerja. Ini adalah alasan yang bagus untuk menggunakan pemrograman asinkron. Dengan pemrograman async, utas tidak diblokir saat permintaan ditangani, jadi keempat utas akan segera dibebaskan. 

Pengaturan benang yang direkomendasikan

Mengingat cara kerja kumpulan thread .Net dan apa yang telah kita diskusikan sejauh ini, sangat disarankan agar Anda mengubah nilai konfigurasi minimum — nilai default — untuk thread pekerja dan IOCP. Untuk melakukan ini di ASP.Net, Anda harus mengubah pengaturan minWorkerThreadsdan minIoThreadskonfigurasi di bawah elemen konfigurasi di file machine.config di sistem Anda.

           minIoThreads = ”berikan nilai yang Anda inginkan di sini” />

Anda dapat menetapkan nilai konfigurasi minimum untuk pekerja dan utas IOCP ke nilai apa pun antara satu dan 50. Pendekatan yang baik adalah dengan mengambil proses dump mode pengguna dari proses pekerja IIS (W3wp.exe) dan kemudian menggunakan !threadpoolperintah untuk melaporkan jumlah total pekerja benang. Setelah Anda mengetahui nilai ini, cukup bagi dengan jumlah inti prosesor di sistem Anda untuk menentukan pekerja minimum dan pengaturan thread IOCP. Misalnya, jika jumlah total utas pekerja adalah 100 dan Anda memiliki empat prosesor di sistem, Anda dapat menyetel nilai minimum untuk utas pekerja dan IOCP menjadi 25.

Untuk mengubah pengaturan utas minimum default di luar ASP.Net, Anda dapat menggunakan ThreadPool.SetMinThreads()metode ini.

Dengan tujuan manajemen utas yang lebih baik dan kinerja yang ditingkatkan, kumpulan utas CLR telah ditingkatkan dengan setiap versi CLR. Sebagai contoh, dengan .Net Framework 4, CLR memperoleh algoritme pencurian utas dan dukungan untuk konkurensi dan paralelisme. Dengan setiap versi baru CLR, kumpulan utas .Net menjadi semakin pintar dalam mengoptimalkan throughput dengan membuat dan menghancurkan utas sesuai kebutuhan. Sementara itu, Anda ingin bereksperimen dengan pengaturan utas minimum yang berbeda untuk mendapatkan kinerja terbaik dari aplikasi .Net Anda.