"장치에서 Windows 쓰기 캐시 버퍼 플러시 해제"의 전체 기능 및 효과


11

Windows 7에서는 장치 관리자를 사용하여 디스크 속성을 불러오고 정책 탭으로 이동하면 2 개의 스위치 항목이 있습니다. 쓰기 캐시.이 질문은 중요하지 않습니다.

[X] 장치에서 Windows 쓰기 캐시 버퍼 플러싱을 끄십시오 .

Microsoft는 해당 항목의 탭에 고지 사항을 적용합니다. "데이터 손실을 방지하기 위해 장치에 전원이 손실 된 경우 버퍼를 플러시 할 수있는 별도의 전원 공급 장치가없는 경우이 확인란을 선택하지 마십시오."

간단히 말해서, 파일 작성, 파일 저장, 파일 복사에 대해이 변경은 무엇입니까?

1. 편집증 프로그램에 대한 쓰기 동작 변경 : (사실 또는 허구)
캐시 플러시가 발생하도록하는 프로그램에 대해 쓰기 플러시 작동 방식을 변경합니까? 일부 프로그램은 추측없이 쓰기를 마치려는 의도가 있습니다. 이러한 프로그램은 보호 쓰기를 계속할 수 있습니까?

2. 영향을받는 프로그램 유형 :
변경으로 인해 영향을 받거나받지 않는 행동 / 프로그램 유형은 무엇입니까? 유형, 일부 프로그램 스트림, 일부는 빠른 쓰기, 일부는 연속적, 일부는 보호 (또는 간단한 용어로 정의 할 수있는 다른 유형)입니다.

3. 당신은 아무것도 보았거나 벤치 마크를 보았습니까 :
설정이 켜져 있다면, 눈에 띄는 변화는 무엇입니까? 관찰 된 행동 변화의 느슨한 예. 또는 행동의 변화가 관찰되지 않았습니까?

4. 지연 또는 지연이란 무엇입니까?
우리는 대부분의 컴퓨터에서 이러한 작업이 매우 빠르다는 것을 알고 있으며 결과적으로 데이터가 기록됩니다. 드라이브 속도와 관련하여 시간이 중요합니까?

내 질문의 목적 상, 존재하는 위험은 질문 중 하나가 아니며, 그것을 덮고 싶다면 방해하지 않습니다.

"캐시 버퍼 플러시 쓰기"의 의미 는 이것의 거의 전부이지만 링크는 다른 OS에 대한 것입니다. A에는 info가 있지만 링크에 사용 된 용어조차 동일하지 않습니다. 또한 사용자가 알고 싶어하는 가장 중요한 사항에 대해서는 대답하지 않습니다.



1
NTFS는 저널링을 사용하여 파일 시스템 메타 데이터 손상을 방지하지만 (파일 내용이 저널링되지는 않지만) 특정 쓰기가 올바른 순서로 발생할 수있는 경우에만 작동하며 Windows는 특정 순서로 쓰기 캐시를 플러시하여 올바른 순서를 보장합니다.
David

답변:


9
  1. 첫 번째 질문에서 당신의 주장은 허구입니다. 로 Windows API는 호출 됩니다 여전히 데이터도 사용할 수 플러싱 버퍼 쓰기로, 물리적 미디어에서 모든 방법을 얻을 수 있는지 확인합니다. 따라서 "안전한"프로그램과 그들이하는 일을 잘 알고있는 프로그램은 괜찮을 것입니다. 같은 호출 결국이 API를 호출 등, .NET있다.FlushFileBuffers() FileStream.Flush()

  2. FlushFileBuffers()직접 호출하지 않고 많은 디스크 I / O를 수행하는 프로그램 또는이 를 호출 하는 도우미 API는 가장 눈에 띄는 성능 향상을 볼 수 있습니다. 예를 들어 BOINC와 같이 데이터가 손실 된 경우 (필수하지 않은 경우 파일을 다시 다운로드하거나 계산을 다시 계산하려고 시도하는 경우) 비 필수 I / O를 실행하는 경우 호출을 피할 수 있습니다. 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)에 기록 된 데이터 만 기록됩니다.
  • 블록 (1)과 (2)의 데이터를 덮어 쓰는 라인 10과 13에서 발생하는 쓰기는 디스크에 다시 쓰여 져야합니다.
  • 따라서 블록 (1)이 RAM에 쓴 총 횟수 는 3이고 디스크 에 2입니다. 블록 (2)가 RAM에 쓴 총 횟수 는 2이고 디스크 에 2입니다.

자동 5 초 버퍼 플러싱을 끈 상태 (질문의 확인란 효과) :

  • 라인 2, 5, 7, 10 및 13에서 발생하는 쓰기 는 RAM에서 발생 하며 라인 14가 실행될 때까지 디스크가 이동하지 않고 라인 10 및 13의 최신 데이터가 블록에 기록됩니다 (1). 및 (2). 2, 5, 7 행의 이전 데이터는 절대 하드 디스크에 닿지 않습니다!

사용량이 많은 시스템이 초당 수십만에서 수십만 번의 파일 쓰기를 경험할 수 있다는 점을 고려하면 성능, 특히 기존의 회전하는 하드 드라이브 (SSD에서는 덜 인상적 임)에 좋습니다. RAM은 일반적으로 하드 드라이브보다 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() `
// ...

그리고“장치에서 Windows 쓰기 캐시 버퍼 플러시 끄기”옵션을 활성화 한 상태에서 Samsung 950pro NVMe 디스크에서 실행하십시오.

결과는 다음과 같습니다.

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시스템 에서 요청이 생략되지 않은 것을 볼 수 있습니다 ( FlushFileBuffers옵션이 활성화 된 경우에도 Windows는 호출을 무시하지 않습니다 ).


답변에서 해설을 삭제하십시오. 해설을 답으로 제출하는 것은 결코 용납 되지 않습니다 .
Ramhound

@ ASBai : (1) C ++을 알고 있습니다 ( 귀하의 프로그램이 작성된 것으로 가정 합니다).하지만 Windows API를 모른다. 코드를 조금 설명해 주시겠습니까? (곰의 일부 사용자 마음에 슈퍼 사용자가 전혀 프로그래머가 아닌, 그 자체 .) 특히, 무엇을 swTest(그리고 왜 선언되지 않은)? (2) 프로그램 사본 두 개를 작성했는데, 그 중 하나는 sfTest.Flush()통화를 포함 하고 다른 하나는 주석 처리하지 않은 상태에서 비교 한 것입니까? 설명 해주십시오. (3) 나는 영어를 알고 있지만, 당신의 마지막 문장을 이해할 수 없습니다.
Scott

@Ramhound 그러나 투표하거나 의견을 남길만한 명성이 충분하지 않습니다.
ASBai

@Scott (1), swTest는 고해상도 타이머이며 Windows 플랫폼에서 QueryPerformanceCounter API를 사용하여 타이밍을 수행합니다 (중요한 지점이 아니라고 생각합니다 :-). (2) 그렇습니다. (3) 나쁜 영어에 대해 죄송합니다. ChatBot John Cavil이 옳 FlushFileBuffers습니다. 옵션이 활성화되어 있어도 Windows는 통화를 무시하지 않습니다. ). 답변에 댓글을 더 추가하겠습니다. 감사합니다 :-)
ASBai

@ASBai-답변으로 해설을 제출해서는 안됩니다. 코멘트는 절대 답변으로 제출해서는 안되므로 코멘트를 제출하는 데 필요한 평판이 없습니다.
Ramhound
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.