Untuk komunikasi Antar-tugas atau untuk berbagi data antara dua tugas RTOS, Kami menggunakan Antrian. Tetapi Masalah dengan Antrian adalah bahwa mereka lambat .... Mereka menyalin data dalam Buffer kemudian Penanganan Mutex dan kemudian Transfer Data. Sangat menjengkelkan lambat jika Anda harus mentransfer data besar. Masalah lain adalah jika antrian yang sama diakses oleh Banyak tugas. Kemudian Gambar menjadi seperti ini: - Pertama Tunggu untuk mendapatkan akses ke Antrian lalu Antrian Penanganan Mutex internal kemudian Transfer Data.
Ini meningkatkan overhead pada sistem. Apa yang bisa menjadi pengganti Antrian yang Efisien ?
(Saya kira pertanyaan ini Independen dari RTOS yang kami gunakan. Sebagian besar RTOS menangani Antrian dengan cara ini saja)
Jawaban:
Antrian beroperasi seperti itu karena itu adalah model transaksi yang aman untuk komunikasi antar-tugas. Anda berisiko mengalami korupsi data dan / atau masalah kepemilikan dalam skema yang tidak terlalu ketat.
Apakah Anda menyalin data ke buffer di memori kemudian meneruskan pointer dengan elemen antrian, atau mencoba meneruskan semua data dalam elemen antrian sendiri? Jika Anda tidak melewati pointer maka Anda akan mendapatkan peningkatan kinerja melakukan itu daripada melewati satu byte pada suatu waktu melalui elemen antrian.
sumber
Salah satu cara mudah adalah dengan meletakkan pointer ke data pada antrian dan mengkonsumsi data menggunakan pointer.
Perhatikan bahwa Anda memperdagangkan keamanan untuk kinerja dengan cara ini karena Anda harus memastikan bahwa:
Jika Anda tidak menggunakan memori yang dialokasikan secara dinamis, Anda tidak harus membatalkan alokasi, tetapi Anda masih harus memastikan bahwa area memori tidak digunakan kembali sebelum data dikonsumsi.
sumber
Antrian bebas-kunci dapat diterapkan untuk kasus produsen tunggal / konsumen tunggal, dan seringkali Anda dapat merancang perangkat lunak Anda untuk meminimalkan jumlah antrian banyak produsen atau banyak konsumen.
Antrian bebas-penguncian dapat dibuat seperti ini: Mengalokasikan array elemen yang akan dikomunikasikan, dan juga dua bilangan bulat, menyebutnya Head and Tail. Head adalah indeks ke dalam array, di mana item berikutnya akan ditambahkan. Ekor adalah indeks ke dalam array, di mana item berikutnya tersedia untuk dihapus. Tugas produsen membaca H dan T untuk menentukan apakah ada ruang untuk menambahkan item; menulis item pada indeks H, kemudian memperbarui H. Tugas konsumen membaca H dan T untuk menentukan apakah ada data yang tersedia, membaca data dari indeks T, lalu memperbarui T. Pada dasarnya itu adalah buffer cincin yang diakses oleh dua tugas, dan urutan operasi (masukkan, lalu perbarui H; hapus, lalu perbarui T) memastikan bahwa korupsi data tidak terjadi.
Jika Anda memiliki situasi dengan beberapa produsen dan satu konsumen, atau satu produsen dan beberapa konsumen, Anda secara efektif memiliki keterbatasan sumber daya, dan tidak ada yang lain selain menggunakan sinkronisasi, karena pembatas kinerja lebih mungkin untuk jadilah produsen / konsumen tunggal daripada overhead OS dengan mekanisme penguncian.
Tetapi jika Anda memiliki banyak produsen DAN konsumen, ada baiknya menghabiskan waktu (dalam desain-ruang) untuk melihat apakah Anda tidak bisa mendapatkan mekanisme komunikasi yang lebih terkoordinasi; dalam kasus seperti ini, membuat serialisasi segala sesuatu melalui satu antrian pasti menjadikan efisiensi antrian sebagai penentu utama kinerja.
sumber
Seseorang bisa mendapatkan operasi yang efisien dalam antrian konsumen tunggal multi-produsen bebas-kunci jika antrian itu sendiri menyimpan barang-barang yang cukup kecil untuk bekerja dengan beban-toko-eksklusif, perbandingan-pertukaran, atau primitif serupa, dan satu dapat menggunakan nilai yang dipesan atau nilai yang dipesan untuk slot antrian kosong. Saat menulis ke antrian, penulis melakukan pertukaran-perbandingan untuk mencoba menyimpan datanya ke slot kosong berikutnya; jika gagal, penulis mencoba slot berikut. Meskipun antrian mempertahankan pointer ke slot kosong berikutnya, nilai pointer adalah "advisory". Perhatikan bahwa jika suatu sistem menggunakan pertukaran-pertukaran dan bukan-toko-eksklusif, mungkin perlu memiliki 'keluarga' dengan nilai 'slot kosong' yang berbeda. Kalau tidak, jika antara waktu penulis menemukan slot antrian kosong dan mencoba untuk menulis kepadanya, penulis lain menulis slot dan pembaca membacanya, penulis pertama tanpa sadar akan meletakkan datanya di tempat di mana pembaca tidak akan melihatnya. Masalah ini tidak terjadi dalam sistem yang menggunakan load-store-eksklusif, karena toko-eksklusif akan mendeteksi bahwa data telah ditulis meskipun itu ditulis kembali ke nilai lama.
sumber
Anda dapat mengakses antrian dengan lebih efisien dengan menulis di atas antrian. Biasanya sebagian besar RTOS memang memberikan dukungan untuk menambahkan ke depan antrian yang tidak memerlukan perolehan mutex. Tetapi pastikan Anda menggunakan menambahkan ke depan antrian seminimal mungkin di mana Anda hanya ingin mengeksekusi data lebih cepat. Biasanya struktur antrian memiliki batas ukuran maksimal sehingga Anda tidak boleh memasukkan semua data ke dalam antrian, sehingga melewati penunjuk selalu mudah.
Bersulang!!
sumber
Antrian pada dasarnya tidak lambat. The pelaksanaan dari mereka mungkin.
Jika Anda menyalin data secara membabi buta dan menggunakan antrian yang sinkron, Anda akan melihat peningkatan kinerja.
Seperti yang ditunjukkan poster lainnya, ada alternatif bebas kunci. Kasus produsen tunggal / konsumen tunggal sangat mudah; untuk banyak produsen dan konsumen, algoritma antrian kunci-bebas oleh Michael dan Scott (itu adalah nama belakang mereka) adalah standar, dan digunakan sebagai dasar untuk Java ConcurrentLinkedQueue Java .
Mungkin untuk mengoptimalkan kebutuhan antrian dalam kasus-kasus tertentu, tetapi mereka memberikan jaminan konkurensi yang biasanya memberikan manfaat penyederhanaan yang sangat besar pada sistem dengan memungkinkan Anda untuk memisahkan tugas.
sumber