2017-02-22 1 views
4

왜 결과 아래의 코드 :.NET async가 파일 복사를 기다리는 이유는 동기 File.Copy() 호출보다 CPU 사용량이 훨씬 많기 때문입니까?

.NET async file copy

public static class Program 
{ 
    public static void Main(params string[] args) 
    { 
     var sourceFileName = @"C:\Users\ehoua\Desktop\Stuff\800MFile.exe"; 
     var destinationFileName = sourceFileName + ".bak"; 

     FileCopyAsync(sourceFileName, destinationFileName); 

     // The line below is actually faster and a lot less CPU-consuming 
     // File.Copy(sourceFileName, destinationFileName, true); 

     Console.ReadKey(); 
    } 

    public static async void FileCopyAsync(string sourceFileName, string destinationFileName, int bufferSize = 0x1000, CancellationToken cancellationToken = default(CancellationToken)) 
    { 
     using (var sourceFile = File.OpenRead(sourceFileName)) 
     { 
      using (var destinationFile = File.OpenWrite(destinationFileName)) 
      { 
       Console.WriteLine($"Copying {sourceFileName} to {destinationFileName}..."); 
       await sourceFile.CopyToAsync(destinationFile, bufferSize, cancellationToken); 
       Console.WriteLine("Done"); 
      } 
     } 
    } 
} 

File.Copy() 상태 :

Sync File Copy

그래서 거기 여전히 : https://msdn.microsoft.com/en-us/library/system.io.file.copy(v=vs.110).aspx이 훨씬 덜 CPU가 걸린다 비동기/파일 복사 목적을 기다리는 진정한 관심사?

가치가 있을지 모르지만 File.Copy 창 기능이 CPU % 측면에서 전투에서 승리하는 것으로 보입니다. 어떤 사람들은 그것이 실제 DMA 지원으로인데도 논쟁 하겠지만, 여전히 나는 공연을 망치기 위해 무엇을하고 있는가? 아니면 비동기 메서드로 CPU 사용을 향상시키기 위해 수행 할 수있는 작업이 있습니까?

+0

더 빠르지 만? – Steve

+0

@Steve 많이 빠르지는 않지만, 나는 여전히 CPU가 걱정하고 있습니다. 무서운 것 같습니다. – Ehouarn

+1

아마도'File.Copy'가 구현 된 방식과'File.OpenRead'와'File.OpenWrite'를 사용하는 직접적인 스트림 기반 접근 방식의 차이점과 관련이 있습니다. 싱크 대 비동기와 관련이 있는지 의심 스럽다. – Abion47

답변

3

File.OpenRead(sourceFileName)public FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false), 즉 비동기 I/O의 경우 false과 동일합니다. File.OpenWrite에 해당하는 내용입니다.

이와 같이 어떤 XXXAsync 작업도 비동기 I/O를 사용하지 않지만 스레드 풀 스레드를 사용하여 가짜 작업을 수행합니다.

그래서 비동기 I/O의 이점을 얻지 못하고 적어도 하나의 스레드를 낭비합니다. I/O에 대해 차단하려는 추가 스레드가 있습니다. 나는 일반적으로 비동기가 동기화보다 약간 느린 성능을 수행 할 것으로 기대한다. (비동기는 일반적으로보다 나은 확장 성을 위해 일회성 속도를 희생한다.) 그러나 이것은 전체적인 것을 포장하는 것보다 조금 나아질 것을 확실히 기대한다. Task.Run() .

나는 여전히 그다지 나쁘지는 않을 것이라고 생각하지만, 어쩌면 안티 멀웨어는 .exe로 작성하여 걱정할 것입니다.

더 나은 비 exe 및 비동기 스트림을 복사하는 것이 좋습니다.

+0

사실 나는 Hans의 대답에 대해 논평 할 때, isAsync 매개 변수가 true로 설정되면 CPU 비율이 급격히 감소하지만 속도는 훨씬 느려집니다 (처음에는 파일 복사 속도를 벤치마킹하지 않았지만 File.Copy는 비동기를 기다리는 것보다 2 ~ 3 배 빠르지 만 다시 소금으로 채 웁니다.) 나는 적절한 벤치마킹으로 포스트를 내일 업데이트 할 것이다. 에릭 리 퍼트 (Eric Lippert)의 의견 외에 많은 의미가 있기 때문에 나는 당신의 대답을 받아들입니다. – Ehouarn

+2

비동기 복사가 동기화보다 2 배 더 느리다는 사실을 두려워하지 않을 것입니다. 더 높은 단일 작업 처리량을 원할 때는 사용하지 않을 것입니다. 나는 그 동안 다른 것을하고 싶을 때나 웹 애플리케이션에서 사용할 때 사용합니다. 웹 애플리케이션에서 얼마나 빨리 하나의 요청을 처리하는지에 관해서는별로 신경 쓰지 않습니다. 동시에 많은 사람들이 봉사 할 수 있습니다. –

6

이들은 매우 터무니없는 숫자입니다. 당신은 당신이 생각하는 것을 단순히 측정하지 않습니다. 캐시 된 파일 데이터에 대한 간단한 메모리 대 메모리 복사본 인 사소한 블립을 초과해서는 안됩니다. File.Copy()와 같습니다. 적정한 DDR3 RAM을 갖춘 컴퓨터에서 ~ 35GB/초에서 작동하므로 수십 밀리 초를 넘을 수 없습니다. 파일이 캐시되지 않거나 시스템에 충분한 RAM이없는 경우에도 이러한 종류의 CPU로드를 얻을 수 없으면 코드 대기 중 디스크 대기가 차단됩니다.

당신이 무엇입니까 실제로 보는 것은 설치된 맬웨어 방지 제품의 성능입니다. 실행 파일을 조작하는 프로그램을 볼 때 항상 속옷을 입습니다.

간단하게 확인하거나 사용하지 않도록 설정하거나 제외하고 다시 시도하십시오.

+0

그러나 VS "악성 코드"에 대해 동의하지만, 작업 관리자가 CPU 사용량 측면에서 일정한 증가가 있음을 나타냅니다 (싼 랩톱의 싼 팬은 async await 사용). 다시 말하지만 File.Copy의 구현은 확실히 isAsync param을 사용하여 비동기 구현 cpu %를 약 75 % 낮추는 것이 좋습니다. GitHub의 corefx 코드를 살펴볼 것입니다. 왜냐하면이 코드는 뒷 배경에서 진행되는 것에 대해 여전히 너무 흐릿하게 보입니다. 어쨌든 테스트 환경에 대한 빛을 흘려 주셔서 감사합니다. – Ehouarn

+1

"실제로보고있는 것은 설치된 맬웨어 방지 제품의 성능입니다." - 여기서 무슨 뜻인지 분명히 해줄 수 있니? 안티 멀웨어 제품이 Visual Studio에 표시되는 CPU를 사용하고 있다는 말입니까? 아니면 다른 프로그램이 @ EhouarnPerret의 프로그램에서 더 많은 CPU를 사용하고 있다고 말하는 것입니까? 방금 작업 관리자에서 100 %로 내 코어 8 개를 고정시키는 Prime95를 열었지만 Visual Studio는 여전히 13 %의 CPU 사용량을 보여 주며 작업 관리자는 내 "ConsoleApplication"프로세스에 대해 동일한 수를 표시합니다. – Quantic

+2

프로그램이 수행하는 작업을 관찰하는 프로파일 러의 고급 스러움이 없기 때문에 맬웨어 방지 프로그램으로 인해 발생하는 오버 헤드는 일반적으로 볼 수 없습니다. 메신저를 쏘지 마세요. 프로파일 러를 신뢰하지 않는 또 다른 경우에는 Ask Question 버튼을 클릭하십시오. –