C++ endl didefinisikan untuk menampilkan '\n' diikuti dengan flush. flush() adalah operasi yang mahal, jadi Anda sebaiknya menghindari penggunaan endl sebagai akhir baris default karena dapat menciptakan masalah kinerja yang Anda lihat (dan tidak hanya dengan SMB, tetapi dengan ofstream apa pun dengan flush yang mahal termasuk pemintalan lokal rust atau bahkan NVMe terbaru dengan tingkat keluaran yang sangat tinggi).
Mengganti endl dengan "\n" akan memperbaiki kinerja di atas dengan mengizinkan sistem melakukan buffer sebagaimana dimaksud. Kecuali beberapa perpustakaan mungkin memerah pada "\ n", dalam hal ini Anda mengalami lebih banyak sakit kepala (lihat https://stackoverflow.com/questions/21129162/tell-endl-not-to-flush untuk solusi yang menggantikan metode sync() ).
Sekarang untuk memperumit masalah, flush() hanya ditentukan untuk apa yang terjadi di dalam buffer perpustakaan. Efek flush pada sistem operasi, disk, dan buffer eksternal lainnya tidak ditentukan. Untuk Microsoft.NET "Saat Anda memanggil metode FileStream.Flush, buffer I/O sistem operasi juga dibilas." (https://msdn.Microsoft.com/en-us/library/2bw4h516(v=vs.110).aspx) Hal ini membuat flush sangat mahal untuk Visual Studio C++ karena akan pulang-pergi menulis sampai selesai media fisik di ujung server jauh Anda seperti yang Anda lihat. GCC di sisi lain mengatakan "Pengingat terakhir:biasanya ada lebih banyak buffer yang terlibat daripada hanya yang ada di tingkat bahasa/perpustakaan. Buffer kernel, buffer disk, dan sejenisnya juga akan berpengaruh. Memeriksa dan mengubahnya bergantung pada sistem ." (https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html) Jejak Ubuntu Anda tampaknya menunjukkan bahwa sistem operasi/buffer jaringan tidak dibilas oleh pustaka flush(). Perilaku yang bergantung pada sistem akan menjadi lebih banyak alasan untuk menghindari endl dan flushing secara berlebihan. Jika Anda menggunakan VC++, Anda dapat mencoba beralih ke turunan Windows GCC untuk melihat bagaimana perilaku yang bergantung pada sistem bereaksi, atau sebagai alternatif menggunakan Wine untuk menjalankan Windows yang dapat dieksekusi di Ubuntu.
Secara lebih umum Anda perlu memikirkan kebutuhan Anda untuk menentukan apakah pembilasan setiap baris sesuai atau tidak. endl umumnya cocok untuk aliran interaktif seperti tampilan (kami membutuhkan pengguna untuk benar-benar melihat keluaran kami, dan tidak dalam semburan), tetapi umumnya tidak cocok untuk jenis aliran lain termasuk file di mana overhead pembilasan bisa signifikan. Saya telah melihat aplikasi menyiram setiap penulisan 1 dan 2 dan 4 dan 8 byte... tidak menyenangkan melihat OS menggiling jutaan IO untuk menulis file 1 MB.
Sebagai contoh file log mungkin perlu membilas setiap baris jika Anda men-debug kerusakan karena Anda perlu membersihkan ofstream sebelum kerusakan terjadi; sementara file log lain mungkin tidak perlu membilas setiap baris jika hanya menghasilkan logging informasi verbose yang diharapkan akan membilas secara otomatis sebelum aplikasi dihentikan. Tidak perlu salah satu/atau karena Anda dapat memperoleh kelas dengan algoritme flush yang lebih canggih untuk memenuhi persyaratan tertentu.
Bandingkan kasus Anda dengan kasus kontras dari orang-orang yang perlu memastikan data mereka sepenuhnya disimpan ke disk dan tidak rentan dalam buffer sistem operasi (https://stackoverflow.com/questions/7522479/how-do-i-ensure-data -ditulis-ke-disk-sebelum-menutup-fstream).
Perhatikan bahwa seperti yang tertulis, outFile.flush() tidak berguna karena membilas aliran yang sudah dibilas. Agar bertele-tele, Anda seharusnya menggunakan endl sendiri atau sebaiknya "\n" dengan outFile.flush() tetapi tidak keduanya.
Performa operasi file jarak jauh, seperti baca/tulis, menggunakan protokol SMB dapat dipengaruhi oleh ukuran buffer yang dialokasikan oleh server dan klien. Ukuran buffer menentukan jumlah perjalanan bolak-balik yang diperlukan untuk mengirim data dalam jumlah tetap. Setiap kali ketika permintaan dan tanggapan dikirim antara klien dan server, jumlah waktu yang dibutuhkan setidaknya sama dengan latensi antara kedua belah pihak, yang bisa sangat signifikan dalam kasus Wide Area Network (WAN).
Buffer SMB -- MaxBufferSize dapat dikonfigurasi melalui setelan registri berikut:
HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\SizeReqBuf
Tipe Data:REG_DWORD
Rentang:1024 hingga 65535 (Pilih nilai sesuai kebutuhan Anda di atas 5000)
NAMUN SMB SIGNING memengaruhi ukuran buffer maksimum yang diizinkan. Jadi kita perlu menonaktifkan penandatanganan SMB juga untuk mencapai tujuan kita. Registri berikut perlu dibuat di kedua sisi server dan jika memungkinkan di sisi klien juga.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManWorkstation\Parameters
Nama Nilai:EnableSecuritySignature
Tipe Data:REG_DWORD
Data:0 (nonaktif), 1 (aktifkan)
Saya tidak memiliki reputasi yang cukup untuk memberikan komentar (yang menurut saya akan lebih baik mengingat tingkat verifikasi pada jawaban ini).
Saya perhatikan bahwa satu perbedaan besar dalam jejak level Linux vs Windows Anda adalah Anda menggunakan SMB1 di Linux dan SMB2 di Windows. Mungkin mekanisme batch oplock bekerja lebih baik di samba SMB1 daripada implementasi sewa eksklusif SMB2. Dalam kedua kasus ini harus memungkinkan sejumlah caching sisi klien.
1) Mungkin coba atur level protokol maks yang lebih rendah di Samba untuk mencoba windows dengan SMB12) Validasi bahwa oplock atau sewa eksklusif telah dihapus
Semoga ini membantu :)