none
Задержки на некоторых файлах при создании жестких ссылок RRS feed

  • Вопрос

  • Разрабатываю софт для резервного копирования файлов. При некоторых условиях требуется создание жестких ссылок на предыдущие копии. При создании жестких ссылок в цикле при количестве файлов от 2000 наблюдаю задержку при выполнении функции CreateHardLink. Для чистоты эксперимента попробовал создать отдельно копию каталога(жесткими ссылками) со своей иерархией, содержащего 3500 файлов разных размеров, общим размером около 2-х Гб, и тоже наблюдаю задержки при создании жестких ссылок именно на некоторых файлах. При чем при переименовнии и перемещении в другое место в иерархии каталога этих файлов задержек при создании на них жестких ссылок не наблюдаю. В чем может быть проблема?

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    AnsiString l_dir, l1, l2, l_str;
    bool l_rez = false;
    TStrings  *cListFile = new TStringList();
    LARGE_INTEGER C;
    LARGE_INTEGER D;
    LONGLONG _temp_;
    int xx;
    
    mOriginalPath = "D:\\20130318103007\\";
    ListFiles(mOriginalPath, cListFile, "*.*",1);
    for (int i=4;i<=10;i++)
      {
        l_dir = "D:\\copy_"+IntToStr(i)+"\\";
        for (int j=0;j<cListFile->Count;j++)
          {
            l1 = cListFile->Strings[j];
            l2 = l1.SubString(19,l1.Length());
            l2 = l_dir + l2;
            MyCreateDirectory (l2);
    
            QueryPerformanceFrequency(&C);
            l_rez = CreateHardLink(l2.c_str(), l1.c_str(), NULL);
    
            _temp_ = D.QuadPart     ;
            QueryPerformanceCounter(&D) ;
            if (l_rez)
              {
                 l_str = l2+"; "+FloatToStrF(((double)D.QuadPart-(double)_temp_ )/ (double)C.QuadPart  ,ffFixed,30,20);
                 SaveCSV(l_str);
              }
            else
              {
                 l_str = "ERROR "+l2+"; "+FloatToStrF(((double)D.QuadPart-(double)_temp_ )/ (double)C.QuadPart  ,ffFixed,30,20);
                 SaveCSV(l_str);
              }
    
          }
      }
    
    delete cListFile;
    }
    
    void __fastcall TForm1::SaveCSV(AnsiString p_Str)
    {
    AnsiString p_FileName = "D:\\Stat.csv";
      try
          {
          FILE *l_file = NULL;
          l_file = fopen(p_FileName.c_str(), "at");
          if(l_file)
              {
                fprintf(l_file, "%s; %s\n", DateTimeToStr(Now()), p_Str);
                fclose(l_file);
              }
          }
      catch(Exception *l_Message)
          {
          throw Exception(l_Message->Message);
          }
    }
    
    
    //-----------------------------------------------------void TForm1::MyCreateDirectory(AnsiString pPath)
    {
    AnsiString ss;
    for (int i=4; i<=pPath.Length(); i++)
      {
         if (pPath[i]=='\\')
           {
             ss = pPath.SubString(1,i);
             CreateDirectory((ss).c_str(), NULL);
           }
      }
    }
    
    //-----------------------------------------------------void __fastcall TForm1::ListFiles(AnsiString path, TStrings *List, AnsiString pMask, int pRecurs)
    {
      TSearchRec sr;
    
    if (FindFirst(path+pMask, faAnyFile, sr) == 0)
    {
     do
     {
         if ((sr.Attr & faDirectory)&&(pRecurs==1))
          {
            if (sr.Name!=".")
              if (sr.Name!="..")
                {
                  ListFiles(path+sr.Name+"\\",List,pMask,pRecurs);
                }
          }
          else
           {
             //AnsiString Ext=ExtractFileExt(sr.Name).UpperCase();
             //if (Ext==pExt)
             List->Add(path+sr.Name);
           }
     }
     while (FindNext(sr) == 0);
     FindClose(sr);
    }
    
    }


    • Изменено _Deus_ex_ 28 марта 2013 г. 6:27
    28 марта 2013 г. 5:59

Ответы

Все ответы

  • Вам трассировку стека для CreateHardLink надо сделать, чтобы увдитеть в чем задержка, может издержки синхронизации, может еще что. Хperf-ом или wpa http://msdn.microsoft.com/en-us/performance/cc709422.aspx

    I'm preparing for the exam 70-660 TS: Windows Internals

    profile for sergmat at Stack Overflow, Q&A for professional and enthusiast programmers


    • Изменено sergmat 28 марта 2013 г. 8:16
    • Помечено в качестве ответа _Deus_ex_ 2 апреля 2013 г. 7:35
    • Снята пометка об ответе _Deus_ex_ 3 апреля 2013 г. 7:47
    28 марта 2013 г. 8:02
  • Спасибо, я попробую.
    28 марта 2013 г. 9:01
  • Сделал трассировку утилитой Хperf как Вы посоветовали. Получил следующее: 

    на файлах, на которых наблюдается задержка в несколько секунд при создании ЖС вызовов больше чем, на тех которые выполняются без задержки.

    Результат с задержкой:

        ntdll.dll!_RtlUserThreadStart
        ntdll.dll!__RtlUserThreadStart
        ?!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        user32.dll!DispatchMessageA
        user32.dll!DispatchMessageWorker
        user32.dll!UserCallWinProcCheckWow
        user32.dll!InternalCallWinProc
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        kernel32.dll!CreateHardLinkA
        kernel32.dll!CreateHardLinkW
        ntdll.dll!ZwSetInformationFile
        ntkrpamp.exe!KiFastCallEntry
        ntkrpamp.exe!NtSetInformationFile
        ntkrpamp.exe!IofCallDriver
        fltMgr.sys!FltpDispatch
        fltMgr.sys!FltpLegacyProcessingAfterPreCallbacksCompleted
        ntkrpamp.exe!IofCallDriver
        ntfs.sys!NtfsFsdSetInformation
        ntfs.sys!NtfsCommonSetInformation
        ntfs.sys!NtfsSetLinkInfo
        ntfs.sys!NtfsAddLink
        ntfs.sys!NtfsAddNameToParent
        ntfs.sys!NtfsAddIndexEntry
        ntfs.sys!AddToIndex
        ntfs.sys!PushIndexRoot
        ntfs.sys!NtfsAllocateAttribute
        ntfs.sys!NtfsAllocateClusters
        ntfs.sys!NtfsAllocateBitmapRun
        ntfs.sys!NtfsWriteLog
        ntfs.sys!LfsWrite
        ntfs.sys!LfsWriteLogRecordIntoLogPage
        ntfs.sys!LfsPrepareLfcbForLogRecord
        ntfs.sys!LfsAllocateLbcb
        ntkrpamp.exe!CcPreparePinWrite
        ntkrpamp.exe!CcMapDataForOverwrite
        ntkrpamp.exe!MmCheckCachedPageStates
        ntkrpamp.exe!MiGetPage
        ntkrpamp.exe!MiRemoveAnyPage

    Результат без задержки:

        ntdll.dll!_RtlUserThreadStart
        ntdll.dll!__RtlUserThreadStart
        ?!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        user32.dll!DispatchMessageA
        user32.dll!DispatchMessageWorker
        user32.dll!UserCallWinProcCheckWow
        user32.dll!InternalCallWinProc
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        ntkrpamp.exe!CommonDispatchException
        ntkrpamp.exe!KiDispatchException
        ntkrpamp.exe!DbgkForwardException
        ntkrpamp.exe!DbgkpSuspendProcess
        ntkrpamp.exe!KeFreezeAllThreads

    Можете что-то посоветовать что и где еще посмотреть и как избавиться от этих задержек в несколько секунд, в то время как все остальное выполняется в несколько миллисекунд?

    2 апреля 2013 г. 2:35
  • В стеке "без задержки" - обработка ядром исключения. В стеке "с задержкой" хотя бы вызывается функция CreateHardLink


    I'm preparing for the exam 70-660 TS: Windows Internals

    profile for sergmat at Stack Overflow, Q&A for professional and enthusiast programmers

    2 апреля 2013 г. 6:18
  • В стеке "без задержки" - обработка ядром исключения. В стеке "с задержкой" хотя бы вызывается функция CreateHardLink

         Странно, по идее при возникновении исключения ЖС не должна создаваться, а всё создается и функция возвращает TRUE

    2 апреля 2013 г. 7:48
  • Добавьте свои отладочные символы, чтоб имена ваших функций видно было. DbgkpSuspendProcess вообще усыпляет процесс и вызова CreateHardLink нет, мне кажется что куда-то не туда вы смотрите.


    I'm preparing for the exam 70-660 TS: Windows Internals

    profile for sergmat at Stack Overflow, Q&A for professional and enthusiast programmers

    2 апреля 2013 г. 8:01
  • Добавьте свои отладочные символы, чтоб имена ваших функций видно было. вообще усыпляет процесс и вызова CreateHardLink нет, мне кажется что куда-то не туда вы смотрите.

    Да, Вы правы, смотрел не так. 

    Вот вариант с задержкой, почему то вызывается SockWaitForSingleObject и больше функций  ntfs.sys:

        ntdll.dll!_RtlUserThreadStart
        ntdll.dll!__RtlUserThreadStart
        kernel32.dll!BaseThreadInitThunk
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        - MmtBackup.exe!?
              ws2_32.dll!select
              mswsock.dll!WSPSelect
              mswsock.dll!SockWaitForSingleObject
           
        - kernel32.dll!CreateHardLinkA
              kernel32.dll!CreateHardLinkW
              ntdll.dll!ZwSetInformationFile
              ntkrpamp.exe!KiFastCallEntry
              ntkrpamp.exe!NtSetInformationFile
              ntkrpamp.exe!IofCallDriver
              fltMgr.sys!FltpDispatch
              fltMgr.sys!FltpLegacyProcessingAfterPreCallbacksCompleted
              ntkrpamp.exe!IofCallDriver
              ntfs.sys!NtfsFsdSetInformation
              ntfs.sys!NtfsCommonSetInformation
              ntfs.sys!NtfsSetLinkInfo
              ntfs.sys!NtfsAddLink
              ntfs.sys!NtfsAddNameToParent
              ntfs.sys!NtfsCreateAttributeWithValue
              ntfs.sys!NtfsLookupInFileRecord
              ntfs.sys!NtfsLookupExternalAttribute
              ntfs.sys!NtfsReadFileRecord
              ntfs.sys!NtfsReadMftRecord
              ntfs.sys!NtfsMapStream
              ntkrpamp.exe!CcMapData
              ntkrpamp.exe!CcMapDataCommon

             ntkrpamp.exe!CcGetVirtualAddress

    вариант без задержки:

        ntdll.dll!_RtlUserThreadStart
        ntdll.dll!__RtlUserThreadStart
        kernel32.dll!BaseThreadInitThunk
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        MmtBackup.exe!?
        kernel32.dll!CreateHardLinkA
        kernel32.dll!CreateHardLinkW
        ntdll.dll!ZwSetInformationFile
        ntkrpamp.exe!KiFastCallEntry
        ntkrpamp.exe!NtSetInformationFile
        ntkrpamp.exe!ObCloseHandle
        ntkrpamp.exe!ObpCloseHandle
        ntkrpamp.exe!ObpCloseHandleTableEntry
        ntkrpamp.exe!ObpDecrementHandleCount
        ntkrpamp.exe!IopCloseFile
        ntkrpamp.exe!IofCallDriver
        fltMgr.sys!FltpDispatch
        fltMgr.sys!FltpLegacyProcessingAfterPreCallbacksCompleted
        ntkrpamp.exe!IofCallDriver
        ntfs.sys!NtfsFsdCleanup
        ntfs.sys!NtfsCommonCleanupOnNewStack
        ntfs.sys!NtfsExtendedCompleteRequestInternal
        ntkrpamp.exe!IopfCompleteRequest
     
         


    3 апреля 2013 г. 3:09
  • Ну так на шаре видимо файл, раз сетевые функции в стеке, вот и задержка оттуда.


    I'm preparing for the exam 70-660 TS: Windows Internals

    profile for sergmat at Stack Overflow, Q&A for professional and enthusiast programmers

    • Помечено в качестве ответа _Deus_ex_ 3 апреля 2013 г. 7:47
    • Снята пометка об ответе _Deus_ex_ 3 апреля 2013 г. 7:47
    • Помечено в качестве ответа _Deus_ex_ 3 апреля 2013 г. 8:02
    3 апреля 2013 г. 5:25
  • Ну так на шаре видимо файл, раз сетевые функции в стеке, вот и задержка оттуда.

    Да файл в шаре
    3 апреля 2013 г. 8:02
  •  Странно просто, что задержка не на всех файлах, а примерно на 3-5% из них и не зависит от размера, есть и не большие. Да и не должна все равно 8-10сек создаваться ЖС хоть и по сети(100мбит) на файлики по 10-15Мб да и непонятно почему больший набор функций вызывается из ntfs.sys. В общем проблема понятно в чем, спасибо за ценные советы, буду искать как решать. 
    3 апреля 2013 г. 8:08