Ini mungkin terdengar sebagai pertanyaan aneh, tetapi di departemen saya, kami mengalami masalah dengan situasi berikut:
Kami sedang bekerja di sini pada aplikasi server, yang semakin besar dan semakin besar, bahkan pada titik yang kami pertimbangkan untuk membaginya menjadi bagian-bagian yang berbeda (file DLL), secara dinamis memuat ketika diperlukan dan membongkar sesudahnya, agar dapat menangani masalah kinerja.
Tetapi: fungsi yang kami gunakan, melewatkan parameter input dan output sebagai objek STL, dan seperti yang disebutkan dalam jawaban Stack Overflow , ini adalah ide yang sangat buruk. (Posting ini berisi beberapa ± solusi dan peretasan, tetapi semuanya tidak terlihat sangat solid.)
Jelas kita bisa mengganti parameter input / output dengan tipe C ++ standar dan membuat objek STL dari yang dulu ada di dalam fungsi, tetapi ini mungkin menyebabkan penurunan kinerja.
Apakah boleh untuk menyimpulkan bahwa, jika Anda mempertimbangkan untuk membangun sebuah aplikasi, yang mungkin tumbuh sebesar itu sehingga satu PC tidak bisa mengatasinya lagi, Anda tidak boleh menggunakan STL sebagai teknologi sama sekali?
Latar belakang lebih lanjut tentang pertanyaan ini:
Tampaknya ada beberapa kesalahpahaman tentang pertanyaan: masalahnya adalah sebagai berikut:
Aplikasi saya menggunakan sejumlah besar kinerja (CPU, memori) untuk menyelesaikan pekerjaannya, dan saya ingin membagi pekerjaan ini menjadi beberapa bagian (karena program ini sudah dibagi menjadi beberapa fungsi), tidak sulit untuk membuat beberapa DLL dari aplikasi saya dan meletakkan beberapa fungsi di tabel ekspor DLL tersebut. Ini akan menghasilkan situasi berikut:
+-----------+-----------+----
| Machine1 | Machine2 | ...
| App_Inst1 | App_Inst2 | ...
| | |
| DLL1.1 | DLL2.1 | ...
| DLL1.2 | DLL2.2 | ...
| DLL1.x | DLL2.x | ...
+-----------+-----------+----
App_Inst1 adalah turunan dari aplikasi, diinstal pada Machine1, sementara App_Inst2 adalah turunan dari aplikasi yang sama, diinstal pada Machine2.
DLL1.x adalah DLL, diinstal pada Machine1, sedangkan DLL2.x adalah DLL, diinstal pada Machine2.
DLLx.1 mencakup fungsi yang diekspor1.
DLLx.2 mencakup fungsi yang diekspor2.
Sekarang di Machine1 saya ingin menjalankan function1 dan function2. Saya tahu bahwa ini akan membebani Machine1, jadi saya ingin mengirim pesan ke App_Inst2, meminta instance aplikasi untuk melakukan function2.
Parameter input / output dari function1 dan function2 adalah objek STL (C ++ Standard Type Library), dan secara teratur saya mungkin mengharapkan pelanggan untuk melakukan pembaruan dari App_Inst1, App_Inst2, DLLx.y (tetapi tidak semuanya, pelanggan mungkin meningkatkan Machine1 tetapi bukan Machine2, atau hanya memutakhirkan aplikasi tetapi bukan DLL atau sebaliknya, ...). Tentunya jika antarmuka (parameter input / output) berubah, maka pelanggan terpaksa melakukan upgrade lengkap.
Namun, seperti yang disebutkan dalam URL StackOverflow yang dimaksud, kompilasi ulang App_Inst1 atau salah satu DLL yang sederhana dapat menyebabkan seluruh sistem berantakan, karenanya judul asli dari posting ini, tidak menganjurkan penggunaan STL (C ++ Template Standar Perpustakaan) untuk aplikasi besar.
Saya berharap bahwa dengan ini saya telah menyelesaikan beberapa pertanyaan / keraguan.
Jawaban:
Ini adalah masalah XY klasik yang dingin sekali.
Masalah Anda sebenarnya adalah masalah kinerja. Namun pertanyaan Anda membuatnya jelas bahwa Anda tidak melakukan profiling atau evaluasi lain dari mana masalah kinerja sebenarnya berasal. Alih-alih, Anda berharap bahwa memecah kode Anda menjadi DLL akan secara ajaib menyelesaikan masalah (yang tidak akan, sebagai catatan), dan sekarang Anda khawatir tentang satu aspek dari non-solusi itu.
Sebaliknya, Anda harus menyelesaikan masalah yang sebenarnya. Jika Anda memiliki beberapa file yang dapat dieksekusi, periksa yang mana yang menyebabkan pelambatan. Saat Anda melakukannya, pastikan itu benar-benar program Anda yang menghabiskan semua waktu pemrosesan, dan bukan driver Ethernet yang tidak dikonfigurasi dengan benar atau semacamnya. Dan setelah itu, mulailah membuat profil berbagai tugas dalam kode Anda. Timer presisi tinggi adalah teman Anda di sini. Solusi klasiknya adalah memonitor waktu pemrosesan rata-rata dan kasus terburuk untuk sejumlah kode.
Saat Anda memiliki data, Anda bisa mengetahui cara mengatasi masalah, dan kemudian Anda bisa mengetahui di mana harus mengoptimalkan.
sumber
Jika Anda harus membagi perangkat lunak antara beberapa mesin fisik, Anda harus memiliki beberapa bentuk serialisasi ketika mengirimkan data antar mesin karena hanya dalam beberapa kasus Anda dapat benar-benar mengirim biner yang persis sama di antara mesin. Sebagian besar metode serialisasi tidak memiliki masalah dalam menangani tipe STL sehingga case bukan sesuatu yang akan membuat saya khawatir.
Jika Anda harus membagi aplikasi menjadi Shared Libraries (DLLs) (sebelum melakukan itu karena alasan kinerja, Anda benar-benar harus memastikan bahwa itu benar-benar akan memecahkan masalah kinerja Anda) melewati objek STL bisa menjadi masalah tetapi tidak harus begitu. Seperti yang telah dijelaskan oleh tautan yang Anda berikan, meneruskan objek STL berfungsi jika Anda menggunakan kompiler yang sama dan pengaturan kompiler yang sama. Jika pengguna menyediakan DLL, Anda mungkin tidak dapat dengan mudah mengandalkan ini. Jika Anda memberikan semua DLL dan mengkompilasi semuanya bersama-sama namun Anda mungkin dapat mengandalkannya dan menggunakan objek STL melintasi batas-batas DLL menjadi sangat mungkin. Anda masih harus berhati-hati untuk pengaturan kompiler Anda sehingga Anda tidak mendapatkan beberapa tumpukan berbeda jika Anda melewati kepemilikan objek, meskipun itu bukan masalah khusus STL.
sumber
RAM murah dan karenanya kode tidak aktif murah. Memuat dan membongkar kode (terutama bongkar) adalah proses yang rapuh dan tidak mungkin memiliki pengaruh signifikan pada kinerja program Anda pada perangkat keras desktop / server modern.
Cache lebih mahal tetapi itu hanya mempengaruhi kode yang baru-baru ini aktif, bukan kode yang duduk di memori yang tidak digunakan.
Secara umum program melebihi komputer mereka karena ukuran data atau waktu CPU, bukan ukuran kode. Jika ukuran kode Anda semakin besar sehingga menyebabkan masalah besar, Anda mungkin ingin melihat mengapa hal itu terjadi.
Seharusnya ok selama dll dan executable dibangun dengan kompiler yang sama dan secara dinamis dihubungkan dengan pustaka runtime C ++ yang sama. Oleh karena itu jika aplikasi dan dll terkait itu dibangun dan digunakan sebagai satu unit maka itu seharusnya tidak menjadi masalah.
Yang bisa menjadi masalah adalah ketika perpustakaan dibangun oleh orang yang berbeda atau dapat diperbarui secara terpisah.
Tidak juga.
Setelah Anda mulai menyebarkan aplikasi di beberapa mesin, Anda memiliki banyak pertimbangan tentang bagaimana Anda melewatkan data di antara mesin-mesin itu. Rincian apakah tipe STL atau lebih tipe dasar yang digunakan kemungkinan akan hilang dalam kebisingan.
sumber
Tidak, saya tidak berpikir bahwa kesimpulannya mengikuti. Bahkan jika program Anda didistribusikan di beberapa mesin, tidak ada alasan bahwa menggunakan STL secara internal memaksa Anda untuk menggunakannya dalam komunikasi antar-modul / proses.
Bahkan, saya berpendapat bahwa Anda harus memisahkan desain antarmuka eksternal dari implementasi internal sejak awal, karena yang pertama akan lebih solid / sulit untuk diubah dibandingkan dengan apa yang digunakan secara internal.
sumber
Anda melewatkan inti pertanyaan itu.
Pada dasarnya ada dua jenis DLL. Anda sendiri, dan milik orang lain. "Masalah STL" adalah Anda dan mereka mungkin tidak menggunakan kompiler yang sama. Jelas, itu bukan masalah bagi DLL Anda sendiri.
sumber
Jika Anda membangun DLL dari hierarki sumber yang sama secara bersamaan dengan kompiler dan opsi bangun yang sama, maka itu akan berfungsi dengan baik.
Namun cara "Windows flavoured" untuk memisahkan aplikasi menjadi beberapa bagian yang beberapa dapat digunakan kembali adalah komponen COM . Ini bisa kecil (kontrol individu atau codec) atau besar (IE tersedia sebagai kontrol COM, di mshtml.dll).
Untuk aplikasi server, ini mungkin akan memiliki efisiensi yang sangat buruk ; itu hanya benar-benar layak ketika Anda memiliki aplikasi yang bergerak melalui beberapa fase dalam jangka waktu yang lama sehingga Anda tahu kapan sesuatu tidak akan dibutuhkan lagi. Ini mengingatkan saya pada game DOS menggunakan mekanisme overlay.
Selain itu, jika sistem memori virtual Anda berfungsi dengan baik, ia akan menangani ini untuk Anda dengan membuka halaman kode yang tidak digunakan.
Beli PC yang lebih besar.
Jangan lupa bahwa dengan optimasi yang tepat laptop dapat mengungguli cluster hadoop.
Jika Anda benar - benar membutuhkan banyak sistem, Anda harus berpikir dengan sangat hati-hati tentang batas di antara mereka, karena di situlah biaya serialisasi. Di sinilah Anda harus mulai melihat kerangka kerja seperti MPI.
sumber
Bagian pertama masuk akal (memisahkan aplikasi ke mesin yang berbeda, untuk alasan kinerja).
Bagian kedua (memuat dan membongkar perpustakaan) tidak masuk akal, karena ini adalah upaya ekstra untuk membuat, dan itu tidak akan (benar-benar) memperbaiki keadaan.
Masalah yang Anda gambarkan lebih baik diselesaikan dengan mesin perhitungan khusus, tetapi ini tidak akan bekerja dengan aplikasi (utama) yang sama.
Solusi klasik terlihat seperti ini:
Antara mesin front-end dan komputasi, Anda mungkin memiliki hal-hal tambahan, seperti penyeimbang beban dan pemantauan kinerja, dan menggunakan pemrosesan khusus pada mesin khusus baik untuk caching dan optimisasi throughput.
Ini sama sekali tidak menyiratkan pemuatan / pembongkaran DLL tambahan, atau apa pun yang berkaitan dengan STL.
Yaitu, gunakan STL secara internal seperti yang diperlukan, dan serialkan data Anda di antara elemen-elemen (lihat grpc dan buffer protokol dan jenis masalah yang mereka pecahkan).
Ini mengatakan, dengan informasi terbatas yang Anda berikan, ini memang terlihat seperti masalah xy klasik (seperti kata @Graham).
sumber