ฟังก์ชั่นและผลกระทบทั้งหมดของ“ การปิดการแคชบัฟเฟอร์การเขียนแคชของ Windows บนอุปกรณ์” คืออะไร


11

ใน Windows 7 ใช้ตัวจัดการอุปกรณ์เปิดคุณสมบัติของดิสก์และไปที่แท็บนโยบายมีรายการสลับ 2 รายการ แคชการเขียนซึ่งคำถามนี้ไม่เกี่ยวกับ

และ

[X] ปิดการแคชบัฟเฟอร์การเขียนของ Windows บนอุปกรณ์ <--- อันนี้เท่านั้น!

Microsoft ให้ข้อจำกัดความรับผิดชอบไว้บนแท็บสำหรับรายการนั้น "เพื่อป้องกันข้อมูลสูญหายอย่าเลือกกล่องกาเครื่องหมายนี้เว้นแต่ว่าอุปกรณ์มีแหล่งจ่ายไฟแยกต่างหากที่อนุญาตให้อุปกรณ์ล้างบัฟเฟอร์ในกรณีที่ไฟฟ้าดับ"

กล่าวอย่างง่ายๆสิ่งที่เปลี่ยนแปลงสำหรับการเขียนไฟล์การบันทึกไฟล์การคัดลอกไฟล์

1. การเปลี่ยนการกระทำการเขียนสำหรับโปรแกรมหวาดระแวง: (ความจริงหรือเรื่องแต่ง)
มันเปลี่ยนวิธีการเขียนฟลัชสำหรับโปรแกรมที่บังคับให้ฟลัชแคชเกิดขึ้นหรือไม่? บางโปรแกรมมีความตั้งใจอย่างมากในการเขียนให้จบโดยไม่ต้องคาดเดาโปรแกรมเหล่านี้สามารถป้องกันการเขียนของพวกเขาต่อไปได้หรือไม่หรือการเปลี่ยนแปลงนี้สำหรับโปรแกรมเหล่านั้นด้วยหรือไม่

2. ประเภทของโปรแกรมที่ได้รับผลกระทบ:
ประเภทของการกระทำ / โปรแกรมที่จะหรือไม่ได้รับผลกระทบจากการเปลี่ยนแปลงคืออะไร? ประเภท, บางสตรีมโปรแกรม, บางคนเขียนอย่างรวดเร็ว, บางคนต่อเนื่อง, บางอันมีการป้องกัน (หรือประเภทอื่น ๆ ที่คุณสามารถนิยามด้วยคำง่าย ๆ )

3. คุณเห็นอะไรหรือมาตรฐานแม้:
หากการตั้งค่าเปิดการเปลี่ยนแปลงที่สังเกตได้ในการเขียนคืออะไร? ตัวอย่างที่หลวมของการเปลี่ยนแปลงพฤติกรรมที่สังเกตได้ หรือสังเกตว่าไม่มีการเปลี่ยนแปลงพฤติกรรม?

4. การระงับหรือล่าช้าคืออะไร:
เรารู้ว่าการกระทำเหล่านี้ส่วนใหญ่รวดเร็วมากในคอมพิวเตอร์ส่วนใหญ่ข้อมูลจะถูกเขียนในที่สุด สัมพันธ์กับความเร็วของไดรฟ์เป็นเวลานานหรือไม่

สำหรับวัตถุประสงค์ของคำถามของฉันความเสี่ยงที่มีอยู่ไม่ใช่หนึ่งในคำถามหากคุณต้องการครอบคลุมมันจะไม่ได้รับในทาง

"Write cache buffer flushing" หมายถึงอะไรเกือบจะเป็นคู่ปรับของสิ่งนี้ แต่ลิงก์สำหรับระบบปฏิบัติการอื่น แม้ว่า A มีข้อมูลบางอย่างแม้คำที่ใช้ในลิงก์จะไม่เหมือนกัน นอกจากนี้ยังไม่ตอบสิ่งที่สำคัญที่สุดที่ผู้ใช้ต้องการทราบว่าฉันได้พยายามร่างไว้ที่นี่



1
NTFS ใช้การทำเจอร์นัลเพื่อป้องกันความเสียหายของข้อมูลเมตาของระบบไฟล์ (แม้ว่าเนื้อหาของไฟล์จะไม่ถูกทำเจอร์นัล) แต่จะใช้ได้เฉพาะในกรณีที่การรับประกันบางอย่างสามารถรับประกันได้ว่าจะเกิดขึ้นตามลำดับที่ถูกต้องและ Windows จะล้างแคชการเขียน
David

คำตอบ:


9
  1. การยืนยันของคุณในคำถามแรกคือเรื่องแต่ง การเรียกใช้ Windows API เช่นจะยังคงมั่นใจได้ว่าข้อมูลได้รับการเข้าถึงสื่อทางกายภาพอย่างเต็มที่แม้จะปิดการใช้งานบัฟเฟอร์การเขียน ดังนั้นโปรแกรมที่ "ปลอดภัย" และรู้ว่าพวกเขากำลังทำอะไรอยู่ การโทรเช่นใน. NET ฯลฯ จะเรียก API นี้ในที่สุดFlushFileBuffers() FileStream.Flush()

  2. โปรแกรมที่ทำดิสก์ I / O จำนวนมากโดยไม่ต้องเรียกFlushFileBuffers()โดยตรงหรือตัวช่วย API ใด ๆ ที่เรียกใช้ในที่สุดจะเห็นว่าประสิทธิภาพการทำงานที่สังเกตเห็นได้เพิ่มขึ้น ตัวอย่างเช่นหากคุณใช้งาน I / O ที่ไม่จำเป็นซึ่งก็โอเคหากข้อมูลสูญหายเช่น BOINC (หากสูญหายคุณเพียงดาวน์โหลดไฟล์ใหม่หรือพยายามคำนวณการคำนวณใหม่) คุณสามารถหลีกเลี่ยงการโทรได้FlushFileBuffers()และเพียงแค่เรียก API เช่นWriteFile()- ข้อมูลจะถูกบัฟเฟอร์เพื่อเขียน แต่จริง ๆ แล้วมันจะไม่ถูกเขียนเป็นเวลานานเช่นเมื่อตัวบ่งชี้ไฟล์ถูกปิดหรือเมื่อโปรแกรมออก น่าเสียดายที่เป็นไปได้ว่าหากระบบล่ม (เช่น BSOD) ข้อมูลทั้งหมดจะสูญหายดังนั้นจึงเป็นเรื่องสำคัญมากว่าถ้าคุณจะจัดการกับชนิดของ / ข้อมูลที่ไม่เปลี่ยนที่มีคุณค่าใด ๆ ที่คุณทำโทรFlushFileBuffers()ไม่ว่าจะล้างบัฟเฟอร์ถูกเปิดใช้งานหรือไม่! มิฉะนั้นข้อผิดพลาดของไดรเวอร์แบบง่าย ๆ (เช่นในไดรเวอร์กราฟิกของคุณ) อาจทำให้คุณสูญเสียข้อมูลจำนวนมาก

  3. ไม่พบเกณฑ์มาตรฐานใด ๆ แต่คุณจะสังเกตเห็นได้มากขึ้นด้วยโปรแกรมที่ตรงกับคำอธิบายในรายการที่สองด้านบน

  4. การซิงค์ข้อมูลไปยังดิสก์นั้นทำได้ไม่เร็วนักโดยเฉพาะถ้าทำการวนซ้ำบ่อยครั้ง โดยค่าเริ่มต้นถ้าผมจำได้อย่างถูกต้องจากการอ่านหนังสือของ Windows Internals, NTFS โดยซิงค์เริ่มต้นทั้งหมดบัฟเฟอร์สกปรกระบบแฟ้มไปยังดิสก์ทุก5 วินาที เห็นได้ชัดว่าเป็นการแลกเปลี่ยนที่ดีระหว่างความเสถียรและประสิทธิภาพ ปัญหาเกี่ยวกับการซิงค์ข้อมูลบ่อยครั้งคือทำให้ฮาร์ดไดรฟ์ทำการค้นหาและเขียนจำนวนมาก

พิจารณารหัสเทียมต่อไปนี้:

1: seek to a certain block (1)
2: write a couple megabytes of data into blocks starting at (1)
3: wait 2 seconds
4: seek to another block (2)
5: write some more megabytes of data into blocks starting at (2)
6: seek back to block (1)
7: write some more megabytes of data into blocks starting at (1)
8: wait 10 minutes
9: seek to block (1)
10: write some megabytes of data into blocks starting at (1)
11: wait 5 seconds
12: seek to block (2)
13: write some megabytes of data into blocks starting at (2)
14: explicit call to FlushFileBuffers()

ด้วยการล้างบัฟเฟอร์อัตโนมัติ 5 วินาทีบน :

  • การเขียนที่เกิดขึ้นบนบรรทัดที่ 2, 5 และ 7 เกิดขึ้นใน RAMและดิสก์ไม่เคลื่อนที่จนกระทั่ง 5 วินาทีผ่านไปตั้งแต่การเขียนครั้งแรกจากนั้นข้อมูลล่าสุด (จากบรรทัดที่ 7) จะถูกเขียนลงในบล็อก (1) และ ข้อมูลที่เขียนลงในบล็อก (2) เท่านั้นที่ได้รับการเขียน
  • การเขียนที่เกิดขึ้นบนบรรทัดที่ 10 และ 13 ซึ่งเขียนทับข้อมูลในบล็อก (1) และ (2) ต้องเขียนลงดิสก์อีกครั้ง
  • ดังนั้นจำนวนครั้งทั้งหมดที่บล็อก (1) ถูกเขียนไปที่ RAMคือ 3 และดิสก์ 2 จำนวนทั้งหมดที่บล็อก (2) เขียนไปยัง RAMคือ 2 และดิสก์ 2

ด้วยโดยอัตโนมัติ 5 สองบัฟเฟอร์ล้างออก (ผลของช่องในคำถามของคุณ):

  • การเขียนที่เกิดขึ้นบนบรรทัดที่ 2, 5, 7, 10 และ 13 เกิดขึ้นใน RAMและดิสก์ไม่เคลื่อนที่จนกว่าจะมีการดำเนินการบรรทัดที่ 14 แล้วข้อมูลล่าสุด (จากบรรทัดที่ 10 และ 13) จะถูกเขียนลงในบล็อก (1) และ (2) ข้อมูลเก่าจากบรรทัดที่ 2, 5 และ 7 ไม่เคยโดนฮาร์ดดิสก์!

เมื่อพิจารณาว่าระบบไม่ว่างสามารถพบกับการเขียนไฟล์นับร้อยถึงหมื่นต่อวินาทีนี่เป็นประสิทธิภาพที่ยอดเยี่ยมสำหรับประสิทธิภาพโดยเฉพาะอย่างยิ่งในฮาร์ดไดรฟ์แบบหมุนทั่วไป (มันน่าประทับใจน้อยกว่าใน SSD) แรมเร็วกว่าฮาร์ดไดรฟ์ถึง 20 เท่าโดยทั่วไปแม้ว่าจะมีช่องว่างที่น้อยกว่าสำหรับ SSD

เหตุผลที่พวกเขาบอกว่าคุณควรใช้แบตเตอรีสำรองคือคุณไม่ต้องการให้มีข้อมูลที่เขียนเป็นบัฟเฟอร์ใน RAM 35 นาทีซึ่งไม่ได้เขียนลงดิสก์เพราะโปรแกรมเมอร์ของคุณขี้เกียจและไม่ได้โทรFlushFileBuffers()แล้วก็มี ไฟฟ้าขัดข้อง แน่นอนว่าการสำรองแบตเตอรี่ไม่ได้ป้องกันคุณจากข้อบกพร่องของไดรเวอร์ที่เป็นสาเหตุของ BSOD ....


0

เพื่อรองรับคำตอบของChatBot John Cavilฉันได้เขียนโปรแกรมทดสอบเล็กน้อย:

// ...
byteEx btTest;
btTest.resize(1024*1024, 0xff); // 1MB data

CSysFile sfTest(byT("test.bin"));

swTest.Start(); // Begin timing by call `QueryPerformanceCounter` API
for (UINT i=0; i<10000; ++i) // Write 1MB data for 10000 times
{
    sfTest.SeekBegin();
    sfTest.Write(btTest); // Call `WriteFile` API 
//  sfTest.Flush();       // Call `FlushFileBuffers` API
}
swTest.Stop(); // Calculate the time-consuming start from `swTest.Start() `
// ...

และเรียกใช้งานบนดิสก์ Samsung 950pro NVMe ด้วยตัวเลือก“ ปิดการลบแคชการเขียนแคช Windows บนอุปกรณ์” เปิดใช้งานตัวเลือก

ผลลัพธ์คือ:

D:\tmp> test        // without sfTest.Flush();
00:00:00.729766     // use 0.73 seconds without FlushFileBuffers()

D:\tmp> test        // with sfTest.Flush();
00:00:06.736167     // use 6.74 seconds with FlushFileBuffers()

ดังนั้นคุณสามารถเห็นFlushFileBuffersคำขอไม่ได้ถูกละเว้นโดยระบบ (Windows จะไม่เพิกเฉยต่อการFlushFileBuffersโทรแม้ว่าจะเปิดใช้งานตัวเลือก)


โปรดลบความเห็นของคุณออกจากคำตอบของคุณ มันไม่เคยยอมรับได้ที่จะส่งความเห็นเป็นคำตอบ
Ramhound

@ASBai: (1) ฉันรู้ C ++ (ฉันคิดว่านั่นคือสิ่งที่โปรแกรมของคุณเขียน) แต่ฉันไม่รู้ Windows API คุณช่วยอธิบายรหัสหน่อยได้ไหม? (จำไว้ว่าผู้ใช้บางSuper Userไม่ได้เขียนโปรแกรมที่ทุกคนต่อ se .) โดยเฉพาะอย่างยิ่งสิ่งที่swTest(และทำไมมันไม่ได้ประกาศ)? (2) คุณกำลังบอกว่าคุณได้ทำสำเนาโปรแกรมสองชุดหนึ่งชุดรวมถึงการsfTest.Flush()โทรและอีกรายการหนึ่งที่ไม่ใช่ (กล่าวคือคอมเม้นท์) และเปรียบเทียบกับพวกเขาหรือไม่ กรุณาอธิบาย. (3) ฉันรู้ภาษาอังกฤษ แต่ฉันไม่เข้าใจประโยคสุดท้ายของคุณ
สกอตต์

@ แรมฮาวด์ แต่ฉันไม่มีชื่อเสียงพอที่จะลงคะแนนหรือแสดงความคิดเห็นวิธีการแก้ปัญหาได้อย่างไร
ASBai

@Scott (1), swTest เป็นตัวจับเวลาความละเอียดสูงโดยใช้ QueryPerformanceCounter API บนแพลตฟอร์ม windows เพื่อทำเวลา (ฉันคิดว่ามันไม่ใช่จุดวิกฤติ :-) (2) ใช่แน่นอน (3) ขออภัยในภาษาอังกฤษที่ไม่ดีของฉันฉันแค่อยากจะพูดว่า: ChatBot John Cavil ถูกต้อง Windows ไม่เพิกเฉยต่อการFlushFileBuffersโทรแม้ว่าจะเปิดใช้งานตัวเลือกแล้วก็ตาม (ฉันเห็นบางแหล่งข้อมูลอื่น ๆ เศร้าการโทรจะถูกเพิกเฉยเมื่อเปิดใช้งานตัวเลือกนี้ ) ฉันจะเพิ่มความคิดเห็นเพิ่มเติมในคำตอบขอบคุณ :-)
ASBai

@ASBai - คุณไม่ควรส่งความเห็นเป็นคำตอบ ไม่สำคัญว่าคุณไม่จำเป็นต้องมีชื่อเสียงในการส่งความคิดเห็นเพราะไม่ควรส่งความคิดเห็นเป็นคำตอบ
Ramhound
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.