На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Проецируемые на память файлы , быстродействие и т.д.
    Цитата bobjones @
    если я правильно понял, "промапить"

    Об этом можешь почитать у Рихтера

    Эта тема была разделена из темы "как быстрее"
      Цитата bobjones @
      посмотрел. сотворил тоже самое но с использованием мапа.

      вот только ненужно называть проецируемые в память файлы - мапами, совершенно не понятно что ты имел ввиду, а под мапом в с++ подразумевается нечто другое. >:(
        Цитата Snike @
        мапом в с++ подразумевается нечто другое. >:(

        А в RTS (Real-Time Strategy) под мапом понимается совсем другое.
          Цитата
          под мапом в с++ подразумевается нечто другое.
          под "мапом" я подразумевал проецируемые в память файлы
          CreateFileMapping() и MapViewOf File();

          память DDR 256Mb PC3200 Kingston + DDR 512Mb PC3200 Samsung
          винчестер -SamsungSP 0802N 80Gb , 7200 об/мин

          тест проводился следующим образом:
          *создается файл длиной 104857600 б (100 мб ) содержащий цифру , 0 например
          * запоминается системное время
          *файл обрабатывается тестируемой процедурой
          *берется текущее время и вычетается из запомненного
          *проверяется правильность нового содержимого файла

          код № 3:
          ExpandedWrap disabled
            HANDLE hfile=CreateFile("sourcefile.bin",GENERIC_READ|GENERIC_WRITE,0,
            NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
            if(hfile==(HANDLE)-1)
              { MessageBox(NULL,"error in opening file","error",0);
                return;
               }
            HANDLE hmap=CreateFileMapping(hfile,NULL,PAGE_READWRITE,
            0,0,NULL);
            if(hmap==NULL)
              { MessageBox("NULL,"error in map create","error",0);
                CloseHandle(hfile);
                return;
               }
            DWORD fsh;
            int filesize=GetFileSize(hfile,&fsh);
            filesize+=(((int)fsh)<<32);
            CloseHandle(hfile);
            int fileoffset=0;
             
            while(filesize>0)
            {
            DWORD block=65536;        
            if(filesize<block)
            block=(DWORD)filesize;
             
            PBYTE pbfile=(PBYTE)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,
            (DWORD)(fileoffset>>32),0,block);
             
            for(DWORD i=0;i<block;i++)  pbfile[i]=pbfile[i]+5;        //обработка
            UnmapViewOfFile(pbfile);
            filesize-=block;
            }
            CloseHandle(hmap);
            //дальше идет подсчет времени
          Сообщение отредактировано: trainer -
            Цитата Snike @
            а под мапом в с++ подразумевается нечто другое.
            Что именно в С++ понимается под "мапом"? Достаточно указать пункт стандарта.
              bobjones
              Ты сам то понял, что с MapViewOfFile "натворил" :D
              Младший дворд dwFileOffsetLow = 0, старший тоже dwFileOffsetHigh == fileoffset == 0. В результате ты всегда читаешь и звписываешь одни и теже первые 64К. Осюда и "суперскорость", хотя реально скорость чтения с диска обычно не превышает 50 Мб/с и 100Мб должны читаться не менее или около 2 сек.

              Во-вторых, если размер файла заведомо меньше размера ОЗУ, то делать блочную обработку с Map\Unmap никакого смыла нет - лишь дополнительные тормоза (хоть и не столь значительные по сравнению с временем чтения\записи). Да и ждать чудес от MMF тоже не стоит - при последовательной обработке обычно он не дает выигрыша по сравнению с ReadFile\WriteFile блоками до 64К
                Цитата
                Младший дворд dwFileOffsetLow = 0, старший тоже dwFileOffsetHigh == fileoffset == 0.

                точно, ошибка здесь. надо вот так:
                PBYTE pbfile=(PBYTE)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,0,(DWORD)(fileoffset&0xFFFFFFFF),block);
                fileoffset+=block;

                однако результаты теста не отменяются: 0.521 - 0.540 секунды.

                привожу полный код:

                ExpandedWrap disabled
                  #include <fstream.h>
                  #include <dateutils.hpp>
                  #include <iostream.h>
                  #pragma hdrstop
                   
                  #pragma argsused
                   
                  createfile(int);
                  bool checkfile(int );
                   
                  //---------------------------------------------------------------------------
                  int main(int argc, char* argv[])
                  {
                  int value=0;
                  createfile(value);
                  char * name="sourcefile.bin";
                  SYSTEMTIME tbegin,tend;
                   
                  GetSystemTime(&tbegin);
                  HANDLE hfile=CreateFile(name,GENERIC_READ|
                  GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
                  if(hfile==(HANDLE)-1)
                    { MessageBox(NULL,"error in opening file","",0);
                      return
                      0;
                     }
                  HANDLE hmap=CreateFileMapping(hfile,NULL,PAGE_READWRITE,
                  0,0,NULL);
                  if(hmap==NULL)
                    { MessageBox(NULL,"error in map create","",0);
                      CloseHandle(hfile);
                      return 0;
                     }
                  DWORD fsh;
                  int filesize=GetFileSize(hfile,&fsh);
                  filesize+=(((int)fsh)<<32);
                  CloseHandle(hfile);
                  int fileoffset=0;
                  while(filesize>0)
                  {
                  DWORD block=65536;
                  if(filesize<block) block=(DWORD)filesize;
                  PBYTE pbfile=(PBYTE)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,
                  0,(DWORD)(fileoffset&0xFFFFFFFF),block);
                  fileoffset+=block;
                  for(DWORD i=0;i<block;i++)  pbfile[i]=pbfile[i]+5;
                  UnmapViewOfFile(pbfile);
                   
                  filesize-=block;
                  }
                  CloseHandle(hmap);
                  GetSystemTime(&tend);
                   
                  cout << tend.wSecond - tbegin.wSecond << "\n" << tend.wMilliseconds-tbegin.wMilliseconds;
                  if (checkfile(value+5)) cout << "\nYES!";
                  cin >> name;
                  }
                   
                  //---------------------------------------------------------------------------
                  createfile(int n)
                  {
                  ofstream cf;
                  cf.open("sourcefile.bin",ios::out | ios::binary);
                  for(int i=0;i<104857600;i++)
                  cf.put(n);
                  cf.close();
                  }
                  //-----------------------------------------------------------------
                  bool checkfile(int n)
                  {
                  ifstream in;
                  char *sym;
                  in.open("sourcefile.bin",ios::in|ios::binary);
                  int count=0;
                  for(int i=0;i<104857600;i++)
                  {
                  in.get(*sym);
                  if((int)*sym != n)
                   { cout << "\nERROR IN FILE" << count;
                     return 0;
                   }
                   count++;
                  }
                  in.close();
                  }
                  Цитата
                  Возьми реальный ненулевой файл и посмотри, что получится


                  взял , посмотрел. все равно - 0.5 секунды

                  теперь код вот такой:

                  ExpandedWrap disabled
                    #include <fstream.h>
                    #include <dateutils.hpp>
                    #include <iostream.h>
                    #pragma hdrstop
                     
                    //---------------------------------------------------------------------------
                    #pragma argsused
                     
                    createnewfile();
                     
                    int main(int argc, char* argv[])
                    {
                    createnewfile();
                    char * name="sourcefile.bin";
                    SYSTEM_INFO *sinf=new SYSTEM_INFO;
                    SYSTEMTIME tbegin,tend;
                    GetSystemTime(&tbegin);
                     
                    HANDLE hfile=CreateFile(name,GENERIC_READ|
                    GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
                    if(hfile==(HANDLE)-1)
                      { MessageBox(NULL,"error in opening file","",0);
                        return
                        0;
                       }
                    HANDLE hmap=CreateFileMapping(hfile,NULL,PAGE_READWRITE,
                    0,0,NULL);
                    if(hmap==NULL)
                      { MessageBox(NULL,"error in map create","",0);
                        CloseHandle(hfile);
                        return 0;
                       }
                    DWORD fsh;
                    __int64 filesize=GetFileSize(hfile,&fsh);
                    filesize+=(((int)fsh)<<32);
                    CloseHandle(hfile);
                    __int64 fileoffset=0;
                    while(filesize>0)
                     {
                    DWORD block=sinf->dwAllocationGranularity;
                    if(filesize<block) block=(DWORD)filesize;
                     
                    PBYTE pbfile=(PBYTE)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,
                    (DWORD)(fileoffset>>32),(DWORD)(fileoffset&0xFFFFFFFF),block);
                     
                    if(pbfile==NULL) {
                                      MessageBox(NULL,"Error in view","error",0);
                                      return 0;
                                      }
                    fileoffset+=block;
                    for(DWORD i=0;i<block;i++)  pbfile[i]=pbfile[i]+5;
                    UnmapViewOfFile(pbfile);
                    filesize-=block;
                     }
                    delete sinf;
                    CloseHandle(hmap);
                    GetSystemTime(&tend);
                    cout << tend.wSecond - tbegin.wSecond << "\n" << tend.wMilliseconds-tbegin.wMilliseconds
                    << "\n\nEnd of test";
                    cin >> name;
                    }
                     
                    //---------------------------------------------------------------------------
                    createnewfile()
                    {
                    cout << "creating test file...\n";
                    ofstream cf;
                    cf.open("sourcefile.bin",ios::out | ios::binary);
                    for(int i=0;i<104857600;i++)
                    cf.put(random(256));       // теперь в файл пишутся [псевдо]случайные числа
                    cf.close();
                    cout << "done.\n\n";
                    }


                  Добавлено
                  я намеренно опустил проверку файла после преобразования чтобы не загромождать код
                    Представление о преимуществах MMF по скорости это очень распространенный миф, основанный на голословных отрывочных фразах из официальных док MS и на некорректных сравнениях некоторых горе-популяризаторов. Последовательное чтение данных с диска путем MMF в принципе не может быть быстрее правильно организованного блочного чтения через ReadFile, а на деле часто оказывается чуть медленее, т.к. весь MMF основан на исключениях отказа страниц, обработка которых занимает заметное время.

                    С записью\копированием дело обстоит несколько сложнее, т.к. сюда замешиваются доп.факторы -
                    особенности работы HDD и хитрости ОС. Во-первых, при MMF данные после UnmapView не сразу записываются на диск и могут находиться в ОЗУ неопределенно долго. Считать ли это преимуществом MMF - вопрос спорный, т.к. накопленные страницы могут начать выгружаться на диск в любой неподходящий момент. Например, если прога после копирования переходит в режим ожидания или занимается длительными вычислениями, то это м.б. незаметно, а вот если нужно обработать еще десяток таких же файлов (или размер одного копируемого файла превышает размер ОЗУ), то тут отложенная запись может проявить себя во всей красе. Если же сравнивать по честному и перед UnmapView вызывать FlushView, то время копирования будет примерно таким же как и при обычном Read\Write c тем же размером буфера.

                    Во-вторых, размер буфера при копировании должен быть больше, чем при простом чтении. Но устремлять размер в "бесконечность" смысла нет, т.к. тут есть разумный предел. При чередовании чтения и записи HDD вынужден каждый раз позиционировать головки, на что уходит не менее 60(с)/7200(об/мин) = 8 мс. Поэтому при размере блока 64К у нас только на одно позиционирование в данном случае уходит (100М/64К)*8мс ~ 13 сек. Вычтем 13 из 18-19 сек и получим разумные 5-6 сек = 2*(2.5-3). Но чтобы снизить потери скажем до 5-10%, достаточно при макс.скорости чтения ~50 Мб/с увеличить размер буфера до (10-20)*8(мс)*50(Мб/с) =4-8 Мб (ну можно с запасом до 10-20 Мб - дальше просто смысла нет).

                    Однако при увеличении размера буфера может проявиться еще одна "хитрость" - скорость обычного буферированного чтения может несколько снизиться из-за возрастания числа промахов быстрого чтения из файлового кэша. Например, в WinXP максимальная скорость чтения получается при размере буфера до 64К, а затем резко увеличивается число кэш-промахов и скорость чтения несколько падает (вообще-то это выглядит довольно глуповато - пытаться лезть в кэш, когда размер считываемых данных превышает размер упреждающего чтения). Но если использовать FILE_FLAG_NO_BUFFERING, то ничего подобного не происходит и скорость копирования оказывается всегда выше чем у MMF c FlushView. Ну а если без Flush, то конечно MMF за счет отложенной записи может формально показывать вдвое лучшие результаты.
                    Сообщение отредактировано: leo -
                      все же у filemapping должны быть плюсы - например достаточно простой неоднократный доступ к файлу.
                      допустим, алгоритм, проходящий файл несколько раз. отобразили на память , поработали, записали на диск. по-любому быстрей чем каждый раз читать/ писать на винт.
                        Цитата bobjones @
                        все же у filemapping должны быть плюсы - например достаточно простой неоднократный доступ к файлу.
                        допустим, алгоритм, проходящий файл несколько раз. отобразили на память , поработали, записали на диск. по-любому быстрей чем каждый раз читать/ писать на винт.

                        :yes: :yes:
                        Но для просто копирования, обычный метод чуууточку шустрее.
                          Цитата bobjones @
                          допустим, алгоритм, проходящий файл несколько раз. отобразили на память , поработали, записали на диск. по-любому быстрей чем каждый раз читать/ писать на винт.

                          Зато есть один здоровенный минус: файл > 4Gb на 32-битной архитектуре не обработать.
                            Цитата linuxfan @
                            Зато есть один здоровенный минус: файл > 4Gb на 32-битной архитектуре не обработать.

                            Глупость
                              До тех пор, пока не напорешься так и будешь думать, что глупость.
                              На самом деле, при использовании mmap'а теряется еще одна возможность: потоковая обработка.
                                32 разрядность архитектуры тут не причем...
                                Цитата linuxfan @
                                До тех пор, пока не напорешься так и будешь думать, что глупость.

                                Изв. но почему-то не напоролся :rolleyes:
                                  Цитата Ace @
                                  32 разрядность архитектуры тут не причем...

                                  Как раз-таки причем. Адресное пространство 32-х разрядной машины как раз есть 4Gb.
                                  Но, если я не ошибаюсь, есть способы работы с большими файлами (мапить куски файла, а не целиком), но это уже неудобно.
                                  Сообщение отредактировано: mo3r -
                                    Цитата Ace @
                                    32 разрядность архитектуры тут не причем...

                                    Как раз очень даже причем: как ты будешь адресовать более 4Gb в одном сегменте?
                                    Цитата Ace @
                                    Изв. но почему-то не напоролся :rolleyes:

                                    Возьми образ DVD-5 и попробуй его замапить от первого до последнего байта.
                                    Hint: sizeof(SIZE_T) чему равно на 32-битной платформе, а?

                                    Добавлено
                                    Цитата mo3r @
                                    Как раз-таки причем. Адресное пространство 32-х разрядной машины как раз есть 4Gb.

                                    Э, нет. Виртуальное адресное пространство i386 составляет 64Tb! Но реально он мог адресовать лишь 4Gb физической памяти.
                                    С появлением возможности PAE (Page Address Extension) база адреса стала 36-битной и таким образом современные 32-битные процы могут адресовать 2^36 = 4Gb * 16 = 64Gb физической оперативки.
                                    Цитата mo3r @
                                    Но, если я не ошибаюсь, есть способы работы с большими файлами (мапить куски файла, а не целиком), но это уже неудобно.

                                    Совершенно верно. Это отчетливо видно по аргументам MapViewOfFile: указывается смещение от начала файла, но удобство при таком подходе примерно такое же, как и при блочном чтении.
                                    Основная выгода от маппинга -- это прозрачный произвольный доступ к содержимому файла без необходимости считывать его в память целиком.
                                    Сообщение отредактировано: linuxfan -
                                      linuxfan
                                      1. Сам сказал что есть PAE, и windows ее поддерживает.
                                      2. мапить файл кусками ... если тебе не удобно то извини. по мне так очень и очень удобно. а если набросать проооостенький классец raper для проекции файла, то можно вообще инкапсулировать это дело.... проблем нет никаких, в общем..
                                        Цитата LuckLess @
                                        1. Сам сказал что есть PAE, и windows ее поддерживает.

                                        PAE к mmap никаким боком не относится.
                                        Цитата LuckLess @
                                        2. мапить файл кусками ... если тебе не удобно то извини. по мне так очень и очень удобно. а если набросать проооостенький классец raper для проекции файла, то можно вообще инкапсулировать это дело.... проблем нет никаких, в общем..

                                        Зависит от того, что тебе требуется: если задача сводится к последовательной обработке всего файла от первого до последнего байта, буферизованное чтение будет намного удобнее.
                                        Если нужен рандомный доступ, то написанный руками класс, предоставляющий функции mmap'а с помощью блочного чтения может быть эффективнее, чем mmap, т. к. будет экономиться время на генерацию исключения для отсутствущей в памяти страницы. Только такой подход выглядит не столь прозрачно и отдельные фрагменты уже существующего кода скорее всего придетстя переделывать под работу с этим классом.
                                        mmap -- это же фактически чтение блоками по 4096 байт -- не самый оптимальный вариант, но экономит кучу времени и нервов на относительно небольших (<2Gb) файлах.
                                          Цитата linuxfan @
                                          PAE к mmap никаким боком не относится.

                                          Как так не относится? Больше места - больший файл смогу замапить.

                                          Цитата linuxfan @
                                          Если нужен рандомный доступ, то написанный руками класс, предоставляющий функции mmap'а с помощью блочного чтения может быть эффективнее, чем mmap, т. к. будет экономиться время на генерацию исключения для отсутствущей в памяти страницы.

                                          Ох хоспади. 1-о сключение никак на производительности не скажется.
                                          Обычное чтение может быть выгоднее только в варианте Overlapped IO когда кроме работы с файлом есть еще чем заняться.
                                            Цитата LuckLess @
                                            Как так не относится? Больше места - больший файл смогу замапить.

                                            RTFM про архитектуру современных процов до полного просветления, т. к. для полноценной дискуссии надо бы немного представлять, каким образом логический адрес преобразуется в физический.
                                            Цитата LuckLess @
                                            Ох хоспади. 1-о сключение никак на производительности не скажется.

                                            Ну, во-первых RTFM, но уже о внутренностях современных ОС + прими во внимание, что исключение генерируется для каждой отсутствующей страницы.
                                            Чтобы узнать больше об аппаратных исключениях и о том, как они сказываются на производительности RTFM про процы.
                                            Кстати, после того, как страница прочитана в память, надо еще предпринять дополнительные телодвижения для очистки какого-то кэша страниц (начиная с i486).

                                            Добавлено
                                            Вообще забавно дискутировать о hardware с C++-никами, для которых слово "исключение" -- это throw/try/catch.
                                            Интересно, а кто из присутствующих может обосновать необходимость буферизованного чтения (fread, ifstream)? Современные ОС все равно выполняют read-ahead, т. е. из без этого буферизуют.
                                              Цитата linuxfan @
                                              Интересно, а кто из присутствующих может обосновать необходимость буферизованного чтения (fread, ifstream)? Современные ОС все равно выполняют read-ahead, т. е. из без этого буферизуют.

                                              Меньшим количеством переходов в режим ядра.
                                                Hryak, тогда подтверди неверующему LuckLess'у, что для последовательной обработки файла последовательное чтение большими блоками будет быстрее, чем mmap.
                                                  Цитата linuxfan @
                                                  Hryak, тогда подтверди неверующему LuckLess'у, что для последовательной обработки файла последовательное чтение большими блоками будет быстрее, чем mmap.

                                                  А чего-то я не вижу места, где он утверждал обратное. :)
                                                    название темы "как быстрее" + первый пост с последовательным вычитыванием +
                                                    Цитата LuckLess @
                                                    мапить файл кусками ... если тебе не удобно то извини. по мне так очень и очень удобно. а если набросать проооостенький классец raper для проекции файла, то можно вообще инкапсулировать это дело.... проблем нет никаких, в общем.

                                                    Звучит так, будто мапить по кускам быстрее.
                                                    И по-любому, при чем тут PAE?
                                                    Цитата LuckLess @
                                                    1. Сам сказал что есть PAE, и windows ее поддерживает.
                                                      Цитата linuxfan @
                                                      ...что для последовательной обработки файла последовательное чтение большими блоками будет быстрее...

                                                      Бессмысленно искать подтверждения. Слишком зависит от текущих условий работы системы. И совсем не важно, как именно ты работаешь с файлом (сам читаешь блоками/используешь мэп). Винды в любой момент времени могут засвопить страницу, если посчитают это необходимым (со всеми послед. исключениями и подгрузками). Память в компе одна, а поюзать её жаждят много народу... :lol:
                                                        Цитата Ace @
                                                        Винды в любой момент времени могут засвопить страницу, если посчитают это необходимым (со всеми послед. исключениями и подгрузками).

                                                        Свопятся страницы, которые давно никем не использовались.
                                                        Цитата Ace @
                                                        Слишком зависит от текущих условий работы системы

                                                        Только от состояния дискового кэша.
                                                          Цитата linuxfan @
                                                          Свопятся страницы, которые давно никем не использовались.

                                                          Очень внимательно перечитай последнее предложение в моём посте. А то такие перлы выдаёшь... ;)
                                                            Цитата Ace @
                                                            Очень внимательно перечитай последнее предложение в моём посте. А то такие перлы выдаёшь... ;)

                                                            А теперь включаем логику, здравый смысл и прочие атрибуты мыслительного процесса:

                                                            а) последовательное чтение read'ом:
                                                            1. выделяем блок памяти под буфер (например, 1 метр)
                                                            2. читаем кусок файла в буфер
                                                            3. обрабатываем
                                                            4. если не eof, goto 2
                                                            В итоге имеем обращения к ядру только для чтения и относительно небольшой буфер фиксированного размера

                                                            б) последовательное чтение mmap:
                                                            1. отображаем файл в память
                                                            2. при чтении следующего фрагмента возникает исключение, ОС реально выдеояет память и читает туда кусок файла; при это надо не забыть поправить область дескрипторов страниц и сбросить кэш страниц
                                                            3. файл здоровый, а памяти и так мало => при последующих обращениях ОС будет вынуждена засвопить какую-то страницу (страницы)
                                                            4. goto 2 пока не финиш
                                                            В итоге имеем кучу неприятностей, включая мухлеж со страничной адресацией и своппинг и необходимость в куче свободной памяти.

                                                            Интересно, так что же будет работать быстрее? :whistle:

                                                            P. S. если mmap на read only, то думаю, ОС достаточно умна, чтобы не свопить произвольную страницу, а просто объявить что-нибудь из отображенной области недействительным и воспользоваться освободившимся пространством.
                                                              Цитата linuxfan @
                                                              Чтобы узнать больше об аппаратных исключениях и о том, как они сказываются на производительности RTFM про процы.

                                                              ExpandedWrap disabled
                                                                int main()
                                                                   {
                                                                   int rt = 0;
                                                                   int tm = GetTickCount();
                                                                   for (int j = 5 ; j < 20000; ++j)
                                                                      rt += isSimp (j);
                                                                   std::cout << (double(GetTickCount()) - tm)/1000 << "\n";
                                                                 
                                                                   rt = 0;
                                                                   tm = GetTickCount();
                                                                   for (int j = 5 ; j < 20000; ++j)
                                                                      {
                                                                      rt += isSimp (j);
                                                                      __try
                                                                         {
                                                                         *(int*)0 = 4;
                                                                         }
                                                                      __except(EXCEPTION_EXECUTE_HANDLER)
                                                                         {
                                                                         }
                                                                      }
                                                                   std::cout << (double(GetTickCount()) - tm)/1000 << "\n";
                                                                 
                                                                   }

                                                              Угадай, на сколько посл код будет медленней!?
                                                              А теперь пощитай будут ли исключения генериться с такойже скоростью как и тут?


                                                              Цитата linuxfan @
                                                              Звучит так, будто мапить по кускам быстрее.

                                                              Я тут оспаривал не скорость( ее я нигде не оспариваю) а УДОБНОСТЬ маппинга.
                                                              Если тебе это звучит както подругому - извини.


                                                              Цитата linuxfan @
                                                              RTFM про архитектуру современных процов до полного просветления, т. к. для полноценной дискуссии надо бы немного представлять, каким образом логический адрес преобразуется в физический.

                                                              Читал, не беспокойся. Но про ПАЕ подзабыл, ибо не пользую. Освежил память - действительно ошибся.
                                                                Цитата LuckLess @
                                                                Я тут оспаривал не скорость( ее я нигде не оспариваю) а УДОБНОСТЬ маппинга.

                                                                Я не оспариваю удобство маппинга для относительно небольших файлов. Я же писал, что прозрачность рандомного обращения -- это главное достоинство. Как только начинается отображение кусками то прозрачность теряется и результат получается немногим лучше чем seek & read.
                                                                Цитата LuckLess @
                                                                Угадай, на сколько посл код будет медленней!?

                                                                Я не гадалка и тем более не дурак, чтобы на замерах малых промежутков времени верить чему-то кроме rdtsc. Ты хочешь попытаться убедить меня, что переключение userspace <-> kernelspace + изменение страничных каталогов + сброс кэша страниц -- очень быстрая операция?
                                                                Сравни побайтовое чтение read (ReadFile в WinAPI -- хотя там, конечно, большая часть времени будет тратиться на заталкивание аргументов в стек) и побайтовое чтение fread. Основная разница будет получена как раз за счет минимизирования числа переключений между kernel и userspace.
                                                                P.S. на файле размером 100 байт разницу почуствовать не удастся ;)
                                                                  Цитата linuxfan @
                                                                  Я не оспариваю удобство маппинга для относительно небольших файлов. Я же писал, что прозрачность рандомного обращения -- это главное достоинство. Как только начинается отображение кусками то прозрачность теряется и результат получается немногим лучше чем seek & read.

                                                                  Ну так я и написал, что написав простенький класс оболочку над мапингом, можно добиться того, что отображение кусками станет прозрачно для пользователя, и удобство не потеряется.


                                                                  Цитата linuxfan @
                                                                  Я не гадалка и тем более не дурак, чтобы на замерах малых промежутков времени верить чему-то кроме rdtsc. Ты хочешь попытаться убедить меня, что переключение userspace <-> kernelspace + изменение страничных каталогов + сброс кэша страниц -- очень быстрая операция?

                                                                  если тебя не устраивает кроошечная погрешность, то простите.
                                                                  но намоем камне 50000 исключений = 1 секунде.
                                                                  50000 исключений = 50000страниц = (приблизительно) 200 МБ.
                                                                  200МБ я копирую за 10 секунд(рейд у меня). значит выходит, что потери на исключениях будут порядка 10 процентов.
                                                                  Еслиб небыло рейда, потери былиб меньше(порядка 5%).

                                                                  На остольном будут еще 1-2 процента потерь. того выходит 7-12%(в зависимости от производительности винта) потерь.
                                                                  Конечно, это довольно большое число.
                                                                  И конечно для копирования файлов маппинг использовать не надо(не только изза производительности, а еще и изза того, что обычное АПИ использовать даже проще!!).
                                                                  Но для рандом акссес маппинг незаменим, вне зависимости от размеров файла.
                                                                    Цитата LuckLess @
                                                                    Ну так я и написал, что написав простенький класс оболочку над мапингом, можно добиться того, что отображение кусками станет прозрачно для пользователя, и удобство не потеряется.

                                                                    Не такой уж он простенький будет. По сути, надо будет написать свое распределение ресурсов (адресное пространство --- это ресурс). А это уже совсем другой калибр.
                                                                      Цитата mo3r @
                                                                      Не такой уж он простенький будет. По сути, надо будет написать свое распределение ресурсов (адресное пространство --- это ресурс). А это уже совсем другой калибр

                                                                      Чего там сложного то.
                                                                      Распределения не надо.
                                                                      есть указатель на буффер, дают адрес, вычисляешь какой кусок надо замапить, смотришь не он ли замаппен, если не он, мапиш другой кусок.
                                                                      очень и очень не сложно.
                                                                        Цитата LuckLess @
                                                                        есть указатель на буффер, дают адрес, вычисляешь какой кусок надо замапить, смотришь не он ли замаппен, если не он, мапиш другой кусок.

                                                                        В этом месте прозрачность уже потеряна, т. к. операции вот такого вот вида:
                                                                        ExpandedWrap disabled
                                                                          len = strlen(mapped);

                                                                        при частичном маппинге уже не покатят. На каждое обращение к отображенной памяти (причем обращение видимо происходит блоками фиксированного размера, т. к. иначе как ты определишь, когда надо еще одну часть мапить?) у тебя происходит выполнение дополнительного кода проверок, который будет выполнять два сравнения (а это три чтения: нижняя граница, верхняя граница и сам адрес), т. е. накладные расходы превышают 300% * размер_указателя (или оффсета) / размер_блока, т. е. если это побайтовое чтение, то накладные расходы на 32-битной архитектуре составят более 1200%!
                                                                        И после этого мы удивляемся, что компы так тормозят!
                                                                          Цитата linuxfan @
                                                                          при частичном маппинге уже не покатят. На каждое обращение к отображенной памяти (причем обращение видимо происходит блоками фиксированного размера, т. к. иначе как ты определишь, когда надо еще одну часть мапить?) у тебя происходит выполнение дополнительного кода проверок, который будет выполнять два сравнения (а это три чтения: нижняя граница, верхняя граница и сам адрес), т. е. накладные расходы превышают 300% * размер_указателя (или оффсета) / размер_блока, т. е. если это побайтовое чтение, то накладные расходы на 32-битной архитектуре составят более 1200%!
                                                                          И после этого мы уд

                                                                          Мдааа..
                                                                          strlen() говоришь? Он применяеться для строк! В данном случае мы работаем с бинарным файлом, и никакой strlen() применен быть не может.
                                                                          Object.size(); вот и вся прозрачность.
                                                                          А про накладные расходы - это вообще сказка.
                                                                          Мне надо хранить
                                                                          1. текущий offset(для точо, чтобы не мапить , что уже замапено)
                                                                          2. размер (можно и не хранить а все время вычислять.)
                                                                          3. Handle файла и мапы.
                                                                          4. Указатель на мапу.
                                                                          5. Размер блока(если вдруг захочеться понастраивать объект, задавая ему разный размер блока)
                                                                          24 байта!! Это очень небольшой расход??? учитывая что без этого объекта нам бы все равно пришлось бы это все вычислять.
                                                                          два сравнения говоришь. Я сейчас просто заплачу.
                                                                          1200% насчитал.
                                                                          побайтовой чтение, мдаа...
                                                                            Цитата LuckLess @
                                                                            Он применяеться для строк! В данном случае мы работаем с бинарным файлом, и никакой strlen() применен быть не может.

                                                                            В файле вполне могут храниться строки.
                                                                              Цитата mo3r @
                                                                              В файле вполне могут храниться строки.

                                                                              нужна строка, пользуй
                                                                              std::ifstream& operator>> (std::ifstream&, std::string&)

                                                                              Не бывает одного инструмента на все! случаи жизни. И таких инструментов не будет никогда.
                                                                                Цитата LuckLess @
                                                                                1200% насчитал.

                                                                                1200% --- это накладные расходы по времени.

                                                                                Добавлено
                                                                                Цитата LuckLess @
                                                                                нужна строка, пользуй
                                                                                std::ifstream& operator>> (std::ifstream&, std::string&)

                                                                                Строки внутри структур данных, например.
                                                                                Цитата LuckLess @
                                                                                Не бывает одного инструмента на все! случаи жизни. И таких инструментов не будет никогда.

                                                                                :yes: Просто с помощью mmf практически слишком сложно работать с файлами размером больше, чем можно адресовать одним указателем.
                                                                                  Цитата mo3r @
                                                                                  1200% --- это накладные расходы по времени.

                                                                                  Без этого класса нам бы тоже пришлось посмотреть тот тли кусок замапен, и тоже мапить другой, если он не замапен.
                                                                                  в случае простого чтения нам бы тоже пришлось посмотреть тот ли кусок прочитан, и прочитать его.
                                                                                  Только этот класс все это дело инкапсулирует!
                                                                                  Накладных расходов тут нет.

                                                                                  Добавлено
                                                                                  Цитата mo3r @
                                                                                  :yes: Просто с помощью mmf практически слишком сложно работать с файлами размером больше, чем можно адресовать одним указателем.

                                                                                  Не сложно, а "накладно".
                                                                                    Цитата LuckLess @
                                                                                    А про накладные расходы - это вообще сказка.
                                                                                    Мне надо хранить
                                                                                    1. текущий offset(для точо, чтобы не мапить , что уже замапено)
                                                                                    2. размер (можно и не хранить а все время вычислять.)
                                                                                    3. Handle файла и мапы.
                                                                                    4. Указатель на мапу.
                                                                                    5. Размер блока(если вдруг захочеться понастраивать объект, задавая ему разный размер блока)
                                                                                    24 байта!! Это очень небольшой расход??? учитывая что без этого объекта нам бы все равно пришлось бы это все вычислять.
                                                                                    два сравнения говоришь. Я сейчас просто заплачу.
                                                                                    1200% насчитал.

                                                                                    Ты меня неправильно понял. Предположим, что у тебя есть прокси-класс, который выполняет отображение различных кусков файла по мере необходимости. Допустим, что для этого класса у тебя определен оператор [], читающий один байт.
                                                                                    Для того, чтобы прочитать один байт из отображенной части файла тебе надо проверить, лежит ли этот байт в уже замапленой части файла или нет (две дополнительных операции чтения + чтение переданного параметра -- номера ячейки). Т. е. для осуществления каждой операции чтения байта нам надо осуществить три операции чтения 32-битных слов и две операции сравнения этих слов.
                                                                                    Кроме того, в "простеньком классе" не обработаешь хорошо случайный доступ -- периодически будет выполняться ремаппинг одних и тех же частей, а для последовательного чтения обычный (f)read проще, удобнее и быстрее.

                                                                                    Добавлено
                                                                                    Цитата LuckLess @
                                                                                    в случае простого чтения нам бы тоже пришлось посмотреть тот ли кусок прочитан, и прочитать его.

                                                                                    В случае простого последовательного чтения никуда смотреть не надо -- мы читаем очередной кусок, обрабатываем его и берем следующий -- мы просто используем правильный алгоритм и не создаем лишних сущностей :)
                                                                                    Не надо стремиться для решения конкретной задачи выбирать наиболее общую абстракцию. Как правило, это не приводит ни к чему хорошему. При решении задачи надо стремиться использовать все имеющиеся естественные ограничения себе на благо.
                                                                                      Цитата linuxfan @
                                                                                      В случае простого последовательного чтения никуда смотреть не надо -- мы читаем очередной кусок, обрабатываем его и берем следующий -- мы просто используем правильный алгоритм и не создаем лишних сущностей :)
                                                                                      Не надо стремиться для решения конкретной задачи выбирать наиболее общую абстракцию. Как правило, это не приводит ни к чему хорошему. При решении задачи надо стремиться использовать все имеющиеся естественные ограничения себе на благо.


                                                                                      Я чувствую мы просто все время о разных вещах говорим :lol: :lol:
                                                                                      Ты говориш берем следующий - это понятно и так)
                                                                                      Я говорю про случай, когда мы не знаем кто следующий!
                                                                                      Например у тебя попросили 5-и миллиардный байт, затем 62-й , затем 3-х миллиардый потом 3-й.
                                                                                      И как ты тут будешь определять кто следующий. Все равно придеться делать эти проверки(о которых я выше говорил).
                                                                                      Но если читать read() - ом , писать это дело будет тяжелее.
                                                                                      Я говорю о произвольном доступе к различным(не последовательным) частям файла. Причем используя кэширующее чтение(т.е. не побайтовое ессесно), с возможностью изменения размера блоков для чтения.

                                                                                      Цитата linuxfan @
                                                                                      Кроме того, в "простеньком классе" не обработаешь хорошо случайный доступ -- периодически будет выполняться ремаппинг одних и тех же частей

                                                                                      Этт непонятно. Я всегда знаю кто уу меня замапен, поэтопу ремаппинг будет только в случае если я замапил уже другой кусок и если я вернусть к старому куску то с большой вероятностью найду его в кеше системы.

                                                                                      Добавлено
                                                                                      Былиб 64-ые процессоры более массовыми... :rolleyes: :rolleyes:
                                                                                        Цитата LuckLess @
                                                                                        Я всегда знаю кто уу меня замапен, поэтопу ремаппинг будет только в случае если я замапил уже другой кусок и если я вернусть к старому куску то с большой вероятностью найду его в кеше системы.

                                                                                        :blink: Это че такое?
                                                                                        Если ты будешь заново мапить старый кусок, то это будет нести те же накладные расходы на перестройку каталогов страниц. Если такой ремаппинг будет частым, то комбинация seek & read вполне сможет его обогнать.
                                                                                        И вообще, не бывает таких задач, чтобы читать совсем рандомные участки файлов (кроме тестов скорости винчестеров). Такую задачу эффективно можно решить только при корректной полной постановке, когда можно будет воспользоваться соображениями о внутреннем устройстве файла, загрузить в память часто используемые области (например, индексы БД) и т. д.
                                                                                        Цитата LuckLess @
                                                                                        Былиб 64-ые процессоры более массовыми... :rolleyes: :rolleyes:

                                                                                        Вообще-то они уже массовые. И на работе, и дома.
                                                                                          Цитата linuxfan @
                                                                                          Вообще-то они уже массовые. И на работе, и дома.

                                                                                          Знаю 1-го челоека с 64-ым камнем.
                                                                                          Сам куплю Конрое..

                                                                                          Цитата linuxfan @
                                                                                          :blink: Это че такое?
                                                                                          Если ты будешь заново мапить старый кусок, то это будет нести те же накладные расходы на перестройку каталогов страниц.

                                                                                          Да. Но не будет чтения с диска, который суть - основной тормоз.
                                                                                          Вспомни, я говорю о удобном но не максимально быстром классе ;)

                                                                                          В побайтовом чтении fseek() + read() то обойтет скорее всего.
                                                                                          Но когда надо работать с диапазонами адресов расположенными в разных участках файла...

                                                                                          В общем, на самом деле, с чем сложно не согласиться, так это с
                                                                                          Цитата linuxfan @
                                                                                          Такую задачу эффективно можно решить только при корректной полной постановке

                                                                                          Так что расссуждать бессмысленно, если нет этой самой полной постановки ;)

                                                                                          ps: я вообще за fstream + отрезания яиц тем, кто лепит большие файлы :lol:
                                                                                            Цитата LuckLess @
                                                                                            ps: я вообще за fstream + отрезания яиц тем, кто лепит большие файлы :lol:

                                                                                            Как жестоко. А вот чтобы не лепить большие файлы и придумали пайпы :)
                                                                                              Цитата linuxfan @
                                                                                              А вот чтобы не лепить большие файлы и придумали пайпы

                                                                                              ёёё...

                                                                                              Цитата linuxfan @
                                                                                              А теперь включаем логику, здравый смысл и прочие атрибуты мыслительного процесса:
                                                                                              ...
                                                                                              б) последовательное чтение mmap:
                                                                                              1. отображаем файл в память
                                                                                              2. при чтении следующего фрагмента возникает исключение, ОС реально выдеояет память и читает туда кусок файла; при это надо не забыть поправить область дескрипторов страниц и сбросить кэш страниц
                                                                                              3. файл здоровый, а памяти и так мало => при последующих обращениях ОС будет вынуждена засвопить какую-то страницу (страницы)
                                                                                              4. goto 2 пока не финиш
                                                                                              В итоге имеем кучу неприятностей, включая мухлеж со страничной адресацией и своппинг и необходимость в куче свободной памяти.

                                                                                              Имхо, в этих этапах логики совсем не увидел. Хотя, если умдрится и такое намыслить, то последнее утверждение про мухлёж вполне справедливо. Вам батенька подизучатьб матчасть...
                                                                                                Цитата Ace @
                                                                                                Вам батенька подизучатьб матчасть...

                                                                                                Нельзя ли указать конкретную главу? :D
                                                                                                  linuxfan > "обосновать необходимость буферизованного чтения (fread, ifstream)? "
                                                                                                  Hryak > "Меньшим количеством переходов в режим ядра"

                                                                                                  Да кто ж об этом задумывается-то :)
                                                                                                  Стандартный размер буфера составляет всего 512 байт и предназначен для чтения текстовых файлов или небольших записей бинарных файлов. Задавать буфер существенно больше смысла нет, т.к. будут заметные потери на копирование данных. Поэтому при чтении больших блоков данных fread читает их напрямую через ReadFile в буфер юзера, но окружает это чтение доп.прибамбасами типа lock\unlock

                                                                                                  linuxfan
                                                                                                  > "для последовательной обработки файла последовательное чтение большими блоками будет быстрее, чем mmap"

                                                                                                  Да действительно, но с некоторыми оговорками. Можно утверждать, что последовательное небуферированное (FILE_FLAG_NO_BUFFERING) чтение блоками >= 64К всегда несколько быстрее чем MMF (разумеется речь идет о реальном (первом) чтении данных с диска, без всяких там хитростей, когда все или часть данных уже находятся в ОЗУ). Но и здесь есть оговорки. Во-первых, длина блока не должна быть слишком большой, т.е. д.б. заведомо меньше размера доступной физ.памяти иначе можно нарваться на свопинг. Во-вторых, если размер самого файла также не превышает размера доступной физ.памяти, то проигрыш MMF оказывается незначительным (на уровне 5-15%). Это связано с тем, что обработка отказов страниц занимает сравнительно небольшой процент от времени чтения данных с диска (см. измышлизмы на эту тему). Наличие\отсутствие упреждающего чтения при MMF - вопрос неясный и может зависеть от версии ОС (по кр.мере в некоторых статьях утверждается, что при маппинге исполняемых образов винда может подгружать за раз более одной страицы). И вообще най мой взгляд главное достоинство небуферированной обработки по сравнению с MMF и обычным буферированным чтением, заключается именно в независимости от особенностей (кривости) реализации тех или иных функций ОС. Например, как я уже говорил, в Win XP обычное чтение хорошо работает с размерами блоков до 64К, а затем наблюдается резкое увеличение числа промахов файлового кэша и соответствущее падение скорости чтения (см. примерчик), поэтому говорить о преимуществе обычного чтения перед MMF можно только с учетом этого ограничения, а не вообще. Зато вроде как XP распознает последовательное чтение и не дает безразмерно расти файловому кэшу. А вот с MMF наблюдается обратная картина - при чтении большого файла XP может "загадить" этим файлом всю физ.память, не соображая, что уже обработанные куски нам больше не понадобятся - в результате подходя к критическому значению она начинает лихорадочно сбрасывать на диск все подряд, что также приводит к падению скорости. Возможно на это как-то можно повлиять (например, ограничением рабочего набора или еще как), но в этом то и основная неприятность - на деле все оказывается не так просто и неизвестно где и на какие виндовые грабли можно наступить, используя ее продвинутые фичи. Поэтому ты прав - лучше уж самому, ручками сделать на основе ясного и понятного Read\Write :)

                                                                                                  PS: мда торможу, тут столько всего понаписали, пока я телился :huh:

                                                                                                  PPS: подредактировал ссылки, т.к. после обновления васма они указывали "пальцем в небо"...
                                                                                                  Сообщение отредактировано: leo -
                                                                                                    leo, респект.
                                                                                                      Чтобы не быть голословным, затестил для сравнения:
                                                                                                      Win XP SP2, HDD Maxtor 80Gb 7200 rpm, RAM DDR400 512Mb, CPU P4 3.2GHz HT-on
                                                                                                      Чтение, модификация и запись на то же место
                                                                                                      ExpandedWrap disabled
                                                                                                        1) Влияние размера блока при фикс.размере CopySize = 100Mб
                                                                                                        Блок  NO_BUF   R\W    MMF+Flush   MMF
                                                                                                        ----  ------  ------  ---------  ------
                                                                                                        64К    7.5      7.5      8.9      2.7  (+ ~2.8 на FlushFileBuffers)
                                                                                                        10М    5.7   < 20.0(!)   5.7      2.7  (- " -)
                                                                                                         
                                                                                                        2) Влияние размера CopySize при фикс.размере блока 10Мб (ОЗУ 512Мб)
                                                                                                        Size   NO_BUF   MMF+Flush    MMF
                                                                                                        ----   ------   ---------   ------
                                                                                                        100M     5.7       5.7        2.7
                                                                                                        512M    29.3      29.9       26.8  (!)
                                                                                                        800M    46.7      46.9      131.1  (!!!)
                                                                                                         
                                                                                                        Методы чтения\записи
                                                                                                          R\W       - обычные буферированные Read\WriteFile
                                                                                                          NO_BUF    - тоже при FILE_FLAG_NO_BUFFERING
                                                                                                          MMF       - "обычный" MMF (без вызова Flush после модификации данных)
                                                                                                          MMF+Flush - то же с вызовом FlushViewOfFile
                                                                                                        Числа в таблицах - число секунд на выполнение операции

                                                                                                      В первой табличке видим:
                                                                                                      - для бесхитростных NO_BUF и MMF+Flush с увеличением размера блока скорость копирования возрастает
                                                                                                      - для обычного R\W при увеличении размера блока наблюдается резкое ухудшение за счет увеличения кэш-промахов (видно по монитору производительности); разброс результатов значительно больше чем в других случаях
                                                                                                      - хитрый MMF без записи на диск держит все модифицированные данные в ОЗУ; если принудительно не вызвать FlushFileBuffers, то эти данные могут сидеть в памяти очень долго - происходит суперленивая фоновая запись и освобождение памяти ~1Мб за несколько секунд. Flush освобождает память примерно за то же время, что и чтение.

                                                                                                      Из второй таблички видно
                                                                                                      - время выполнения предсказуемых NO_BUF и MMF+Flush растет пропорционально размеру файла (точнее - размеру изменяемых данных)
                                                                                                      - MMF+Flush незначительно отличается от NO_BUF (хотя если только читать данные без записи, то разница получается больше ~10%)
                                                                                                      - "обычный" MMF ("быстрый", "простой", "удобный" и как его еще только не величают) из "супербыстрого" при малых размерах копируемых данных "вдруг" превращается в заурядного (но зловредного), когда размер файла приближается к размеру доступной физ.памяти, и в полный отстой когда размер файла заметно больше размера ОЗУ. На консоль производительности без корвалола и валерианы лучше не смотреть - такое впечатление, что хрюша готова пожертвовать собой, лишь бы сохранить по максимуму "драгоценные" даные (хотя на самом деле наверняка действует дебильный принцип LRU, а ограничения на WorkingSize почему-то игнорируются). Ну и разумеется после отработки проги проблемы не кончаются, т.к. доступная физ.память колеблется вблизи нуля и похоже часть системного кода сброшена в своп, поэтому если не сделать Flush или не перезагрузить комп, то придется какое-то время мучится с заторможенной системой. Такая же ситуация может возникнуть и при чистом чтении, если проецировать файл не блоками, а целиком - если суммарный размер прочитанных данных приблизится к критическому, начнется такая же "поросячья истерика". Как с этим бороться я не знаю, неужели в хваленой многозадачной ОС могли допустить такую глупость ? Или есть секретные приемы, не раскрываемые широким массам ?
                                                                                                        Цитата leo @
                                                                                                        Чтобы не быть голословным, затестил для сравнения:

                                                                                                        Уважаемый leo. Хочу обратить твоё внимание на то, что находишься не разделе Windows или Hardware, а в разделе Программирование \ C/C++ \ Чистый С/С++ . Тут программисты тусуются и результаты тестов нужно выкладывать вместе с исходными кодами. "Это не от недоверия к тебе" © д-р Борменталь. У меня, например, прямо щас нет времени писать такие тесты с нуля, но я мог бы взять твой за основу и показать другую сторону медали.
                                                                                                        Цитата
                                                                                                        Чтение, модификация и запись на то же место

                                                                                                        Просто тепличные условия для использования небуферизированного ввода/вывода. По-моему, ни один сторонник MMF в данной ветке не утверждал, что в данных условиях MMF сделает прочие способы. Врочем, по-твоему тесту в ряде случаев так и может получиться. Всё зависит от конкретной задачи - а именно, от последствий ленивой записи. Например, если после обработки программа выдает приглашение пользователю что-нить ввести и начинает ждать, то согласись, что
                                                                                                        Цитата
                                                                                                        Блок NO_BUF R\W MMF+Flush MMF
                                                                                                        ---- ------ ------ --------- ------
                                                                                                        64К 7.5 7.5 8.9 2.7 (+ ~2.8 на FlushFileBuffers)
                                                                                                        вывести приглашение через 2.7 сек - это получше, чем через даже 7.5, не говоря уж о 8.9. Пользователь доволен - программист доволен, а что винт шуршит, пока пользователь читает сообщение и думает, что же ему ответить - да кого это волнует?
                                                                                                        Так что даже здесь у MMF могут быть преимущества. Все решает конкретная задача и её контекст.

                                                                                                        Далее. Разбавь немного свои тепличные условия и добавь в алгоритм работы случайные чтения/запись с уже обработанных страничек. Чем больше - тем больше NO_BUF идет лесом. Результаты R/W и MMF не должны сильном меняться.
                                                                                                        Вопрос - что использовать в таком случае? Думаю, в большинстве случаев не R/W (20c против 2.7 для MMF из твоего теста).

                                                                                                        Цитата
                                                                                                        2) Влияние размера CopySize при фикс.размере блока 10Мб (ОЗУ 512Мб)
                                                                                                        Size NO_BUF MMF+Flush MMF
                                                                                                        ---- ------ --------- ------
                                                                                                        100M 5.7 5.7 2.7
                                                                                                        512M 29.3 29.9 26.8 (!)
                                                                                                        800M 46.7 46.9 131.1 (!!!)

                                                                                                        Еще одна причина, по которой хотелось чутка поправить твои исходники. Где результаты обычного R/W? Или ты решил пожалеть поклонников MMF и не шокировать их прекраснейшими вражескими результатами? :D

                                                                                                        131 сек - это много, конечно, но:
                                                                                                        Цитата leo
                                                                                                        в этом то и основная неприятность - на деле все оказывается не так просто и неизвестно где и на какие виндовые грабли можно наступить, используя ее продвинутые фичи. Поэтому ты прав - лучше уж самому, ручками сделать на основе ясного и понятного Read\Write

                                                                                                        Всё дело в использовании мощного и гибкого инструмента, но сложного инструмента.
                                                                                                        1. Незнание, неумение пользоваться. Например, дай осаждающим замок тысячу лет назад людям артиллерийскую пушку, сказав, что с ее помощью они смогут влегкую высадить ворота, но ничего более не говори. Они попробуют её покатить к воротам, используя как стенобитное орудие, а потом тебя же посадят на кол, сказав, что их старые добрые стенобитные орудия работают гораздо лучше этой штуки (а может, и не попробуют катить, а прикинут сразу, что неудобная штука). Почему тебя посадили на кол? Потому что люди не умели пользоваться инструментом.
                                                                                                        2. Наличие знания, но недостаточное умение. Пример из C: есть указатель на строку и нужно определить, что он указывает на непустую строку. По канонам хорошего стиля нужно было бы писать:
                                                                                                        ExpandedWrap disabled
                                                                                                          if (p != NULL && *p != 0)
                                                                                                        Однако, многие пишут:
                                                                                                        ExpandedWrap disabled
                                                                                                          if (p && *p)
                                                                                                        И я их поддерживаю тут. Да, если новичка заставить читать код, ему, возможно, будет проще понять первую запись, однако, специалист и напишет вторую строчку быстрее, и прочтет ее быстрее. В ней мало символов, а содержимое - шаблон, который сидит в голове.

                                                                                                        Да, к чему это я? :wacko:
                                                                                                        К MMF, конечно. Как и любой другой мощный инструмент, его надо знать - его сильные и слабые стороны.
                                                                                                        Поросячий визг начинается при доступной физ. памяти ~ 0? Дак делай изредка FlushViewOfFile (из результатов всё твоего же теста). Если можешь определить блок, с которым скорее всего не будешь работать - ему делай, не можешь - всему делай. Хотя во втором случае лучше просто рабочий набор уменьшить - пусть система сама сообразит - какие данные более старые и ненужные.

                                                                                                        -юсртыхэю
                                                                                                        Цитата Hryak @
                                                                                                        Почему тебя посадили на кол?

                                                                                                        :wacko: Ты эта...... Серьезно-то не воспринимай. Это всё пары C2H5OH. За клавой-то я еще сижу, а вот стоять мне проблема. :whistle: Ну, и в голову стукает.
                                                                                                          Уважаемый, Hryak.
                                                                                                          Если убрать эмоции, то получится что мы говорим об одном и том же :)
                                                                                                          "Как и любой другой мощный инструмент, его надо знать - его сильные и слабые стороны"
                                                                                                          Золотые слова, применимые не только к MMF, но и к обычному R\W и NO_BUF. Но на деле оказывается, что в официальных доках и в популярных изложениях почему-то выпячивают только сильные стороны, и умалчивают о слабых. В результате складывается впечатление о чудесном супербыстром MMF и умной заботливой винде, которая сделает за нас все, что нужно. Наряду с этими наивно-или-лукаво хвалебными представлениями, на программерских форумах гуляют прямо противоположные мнения тех, кто уже попробовал на вкус этот чудо MMF и напоролся на его подводные камни. Вот и бьются друг с другом до посинения. А я лично "ни за белых, ни за красных - мое дело сторона". Я лишь (без претензий на полноту и всеобщность) пытаюсь на конкретных цифрах проиллюстрировать эти самые сильные и слабые стороны - чтобы "юноши, обдумывающие житье" не верили лозунгам белых и красных, а делали собственные выводы и не наступали на известные грабли.
                                                                                                          Поскольку в данном топике речь идет о модификации файла, то и тестовые примеры ес-но относятся к данному "тепличному" случаю. И приводить в данном случае код, особого смысла не имеет, т.к. тут все тривиально и достаточно просто изменить параметры в уже приведенных вариантах. Единственная проблема - это очистка ОЗУ при повторных проходах. Для NO_BUF ничего чистить не нужно, для MMF можно делать FlushFileBuffers, а вот с обычным R\W проблем больше - нужно или ресетить комп, или тестировать на разных файлах или разных частях одного большого файла. Отсюда и больше мороки, и бОльшой разброс результатов для R\W, и тестить копирование больших объемов мегабайтными блоками - пустая трата времени. А для блоков 64К могу привести доп.цифры: 512Мб за 35.3 с, 800Мб за 52.8 с - все достаточно линейно, т.к. при последовательном чтении\записи размеры кэша и отложенной записи практически не растут. Но это так, к слову :)

                                                                                                          Вывод: у каждого метода есть свои особенности, свои "сильные и слабые стороны". Поэтому использовать их и тем более сравнивать между собой нужно с оговорками, а не вообще, как это к сожалению часто делается
                                                                                                            Цитата leo @
                                                                                                            Но на деле оказывается, что в официальных доках и в популярных изложениях почему-то выпячивают только сильные стороны, и умалчивают о слабых. В результате складывается впечатление о чудесном супербыстром MMF и умной заботливой винде, которая сделает за нас все, что нужно.

                                                                                                            Не видел выпячивания в официальных доках, может приведёшь хоть один официальный источник где тебе навязывают использовать именно ммф, т.к. он чудесный и супербыстрый?
                                                                                                            Тебе предоставили стандартизованный интерфейс работы с обьектами, которые "чудесным образом" могут быть связанны с физическими файлами на дисках. Если желаешь, можешь себе представить это как верхний уровень некоего интерфейса, который берёт на себя всю нудную и черновую работу по взаимодействию с физическими проблемами чтения,записи,выделения памяти,etc... Где тебе, как пользователю этого интерфейса, остаётся направлять поведение в нужное русло и контролировать исполнение твоих желаний.

                                                                                                            Цитата leo @
                                                                                                            Наряду с этими наивно-или-лукаво хвалебными представлениями, на программерских форумах гуляют прямо противоположные мнения тех, кто уже попробовал на вкус этот чудо MMF и напоролся на его подводные камни. Вот и бьются друг с другом до посинения.

                                                                                                            Врядли стоит сильно заморачиватся от мнений тех кто пробовал/не пробовал/всегда в танке. Иногда, достаточно грамотный и знающий обсуждаемую проблему человек, - просто прочитает посты, улыбнётся от потока глупости и её напора, и даже не захочет указать "посиневшим от спора" их неправоту в тех или иных заблуждениях.

                                                                                                            Цитата leo @
                                                                                                            Я лишь (без претензий на полноту и всеобщность) пытаюсь на конкретных цифрах проиллюстрировать эти самые сильные и слабые стороны - чтобы "юноши, обдумывающие житье" не верили лозунгам белых и красных, а делали собственные выводы и не наступали на известные грабли.

                                                                                                            Понимаешь, все эти предоставляемые цифры (я не тебя конкретно сейчас имею в виду), полученные после непонятно каких тестов могут оказывать действия только на тех, кто пребывает в "посиневшим от спора" состоянии. Для того, чтоб оценить справедливость заявленного, требуется предоставить полную раскладку использовавшихся средств, исходный код, полный отчет о состоянии системы на момент тестов, и т.д. и т.п...

                                                                                                            Цитата leo @
                                                                                                            Вывод: у каждого метода есть свои особенности, свои "сильные и слабые стороны". Поэтому использовать их и тем более сравнивать между собой нужно с оговорками, а не вообще, как это к сожалению часто делается

                                                                                                            Вот с этим согласен :)
                                                                                                              Цитата leo @
                                                                                                              Если убрать эмоции

                                                                                                              Какие эмоции? :)

                                                                                                              Цитата
                                                                                                              то получится что мы говорим об одном и том же

                                                                                                              Бесспорно.
                                                                                                                Цитата Hryak @
                                                                                                                Цитата linuxfan @
                                                                                                                Интересно, а кто из присутствующих может обосновать необходимость буферизованного чтения (fread, ifstream)? Современные ОС все равно выполняют read-ahead, т. е. из без этого буферизуют.

                                                                                                                Меньшим количеством переходов в режим ядра.

                                                                                                                Что это означает? Вы хотите сказать при использовании fread, ifstream ОС не занимается буферизацией?
                                                                                                                Или что? Можно об этом подробнее? Меня этот вопрос интересовал когда-то, но разбираться некогда было. И еще: буферизация операционной системой и кеширование - одно и то же, или разные вещи?
                                                                                                                  по поводу выбора оптимального размера буффера....
                                                                                                                  седня потести R/W ..
                                                                                                                  копировался файл 650МБ
                                                                                                                  у меня рэйд
                                                                                                                  в функции main после каждово вызова функции копирования стоит комментарий.. в нем --- сколько секунд длился вызов на моей системе..
                                                                                                                  ExpandedWrap disabled
                                                                                                                    double RWNBCopy (const char* src, const char* dst, DWORD buffsize = 64*1024, DWORD flags = FILE_FLAG_NO_BUFFERING)
                                                                                                                       {
                                                                                                                       HANDLE hFiler = CreateFile (src, GENERIC_READ, 0, 0, OPEN_ALWAYS, flags, 0);
                                                                                                                       if (hFiler == INVALID_HANDLE_VALUE)
                                                                                                                          {
                                                                                                                          std::cout << "Cannot open file for reading, error N " << GetLastError() << "\n";
                                                                                                                          return 0;
                                                                                                                          }
                                                                                                                       HANDLE hFilew = CreateFile (dst, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, hFiler);
                                                                                                                       if (hFilew == INVALID_HANDLE_VALUE)
                                                                                                                          {
                                                                                                                          std::cout << "Cannot open file for writing, error N " << GetLastError() << "\n";
                                                                                                                          return 0;
                                                                                                                          }
                                                                                                                     
                                                                                                                       char* buff = (char*)VirtualAlloc (0, buffsize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
                                                                                                                      
                                                                                                                       DWORD read = 0;
                                                                                                                       int tm = GetTickCount();
                                                                                                                       while (ReadFile (hFiler, buff, buffsize, &read, 0) && read)
                                                                                                                          WriteFile (hFilew, buff, read, &read, 0);
                                                                                                                       double ret = ((double)GetTickCount() - tm)/1000;
                                                                                                                     
                                                                                                                       VirtualFree (buff, buffsize, MEM_DECOMMIT|MEM_RELEASE);
                                                                                                                     
                                                                                                                       CloseHandle (hFiler);
                                                                                                                       CloseHandle (hFilew);
                                                                                                                       return ret;
                                                                                                                       }
                                                                                                                     
                                                                                                                     
                                                                                                                     
                                                                                                                     
                                                                                                                    int main(int, char*)
                                                                                                                       {
                                                                                                                       std::cout << "64KB NB " << RWNBCopy ("E:\\file.avi", "E:\\file2.avi") << "\n"; //24.5
                                                                                                                       std::cout << "4KB NB " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 4*1024) << "\n"; //38.5
                                                                                                                       std::cout << "4MB NB " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 4*1024*1024) << "\n"; //25.5
                                                                                                                       std::cout << "32MB NB " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 32*1024*1024) << "\n"; //22
                                                                                                                       std::cout << "32MB B " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 32*1024*1024, 0) << "\n"; //31
                                                                                                                       }


                                                                                                                  Добавлено
                                                                                                                  512 РАМ
                                                                                                                  остальное вродь как не важно..

                                                                                                                  Добавлено
                                                                                                                  кстати, когда я попробовал задать размер буффера - 64МБ , копирование обломилось с ошибкой...
                                                                                                                  пока не пытался понять почему...

                                                                                                                  Добавлено
                                                                                                                  Предлагаю эту тему дообсуждать , доопсасывать и потом сделать из нее FAQ ..
                                                                                                                    LuckLess, держи, поиграйся :)
                                                                                                                    ExpandedWrap disabled
                                                                                                                      double RWNBCopy (const char* src, const char* dst, DWORD buffsize = 64*1024, DWORD dwTmp = 0)
                                                                                                                      {
                                                                                                                          CxFileMap::ErrorCode eCode;
                                                                                                                          CxFileMap fin, fout;
                                                                                                                          eCode = fin.Open( src);
                                                                                                                          if( eCode != CxFileMap::EC_SUCCESS)
                                                                                                                          {
                                                                                                                              std::cout << "Cannot open file for reading, error N " << DWORD( eCode) << "\n";
                                                                                                                              return 0;
                                                                                                                          }
                                                                                                                       
                                                                                                                          eCode = fout.Create( fin.GetFileSize(), dst, FALSE, FALSE);
                                                                                                                          if( eCode != CxFileMap::EC_SUCCESS)
                                                                                                                          {
                                                                                                                              std::cout << "Cannot open file for writing, error N " << DWORD( eCode) << "\n";
                                                                                                                              return 0;
                                                                                                                          }
                                                                                                                       
                                                                                                                          int tm = GetTickCount();
                                                                                                                       
                                                                                                                          ULARGE_INTEGER uliOffs = {};
                                                                                                                          for(
                                                                                                                              LPVOID pPtrIn = fin.GetView( uliOffs, buffsize);
                                                                                                                              pPtrIn;
                                                                                                                              pPtrIn = fin.GetView( uliOffs, buffsize)
                                                                                                                              )
                                                                                                                          {
                                                                                                                              LPVOID pPtrOut = fout.GetView( uliOffs, fin.GetSizeView());
                                                                                                                              if( !pPtrOut || fout.GetSizeView() != fin.GetSizeView())
                                                                                                                                  break;
                                                                                                                              memcpy( pPtrOut, pPtrIn, fin.GetSizeView());
                                                                                                                              uliOffs.QuadPart += fin.GetSizeView();
                                                                                                                              fout.FlushView();
                                                                                                                          }
                                                                                                                       
                                                                                                                          double ret = ((double)GetTickCount() - tm)/1000;
                                                                                                                       
                                                                                                                          if( uliOffs.QuadPart != fin.GetFileSize().QuadPart)
                                                                                                                          {
                                                                                                                              std::cout << "Error copy data!" << "\n";
                                                                                                                              return 0;
                                                                                                                          }
                                                                                                                       
                                                                                                                          return ret;
                                                                                                                      }

                                                                                                                    Хедер с классиком CxFileMap тут.
                                                                                                                    ЗЫ. В цикле специально делается FlushView, чтоб писалось сразу...

                                                                                                                    Добавлено
                                                                                                                    Цитата LuckLess @
                                                                                                                    остальное вродь как не важно..

                                                                                                                    Эт как это, а если у тя там в это время касперский сканит диски :o
                                                                                                                      Цитата
                                                                                                                      Что это означает? Вы хотите сказать при использовании fread, ifstream ОС не занимается буферизацией?
                                                                                                                      Или что? Можно об этом подробнее? Меня этот вопрос интересовал когда-то, но разбираться некогда было. И еще: буферизация операционной системой и кеширование - одно и то же, или разные вещи?

                                                                                                                      вот цитата из умной книжки:
                                                                                                                      "При выполнении вывода данные не сразу записываются на связанное с потоком физическое устройство, а информация временно сохраняется во внутреннем буфере. Только после заполнения буфера его содержимое переписывается на диск. Однако вызов функции flush()вызывает физическую запись информации на диск до заполнения буфера.Ниже показан прототип функции flush(), являющейся членом потоковых классов вывода:
                                                                                                                      ExpandedWrap disabled
                                                                                                                        ostream &flush();
                                                                                                                      "
                                                                                                                      Г.Шилдт ,самоучитель с++.
                                                                                                                        Цитата Ace @
                                                                                                                        Эт как это, а если у тя там в это время касперский сканит диски :o

                                                                                                                        :D :D Был бы рад еслиб я во время скана Касперским дисков копировал 650МБ за 22сек ))))
                                                                                                                        Кстати сама систем копирует медленне(значительно)... (CTRL+C , CTRL+V имеется ввиду), что странно...
                                                                                                                          LuckLess
                                                                                                                          Интересно, почему ты при создании dst не задаешь flags как в src ?
                                                                                                                          Видимо поэтому результат 64Кб NB получается лучше, чем 4Mb NB - рулит кэшируемая запись

                                                                                                                          Ace
                                                                                                                          Просто копировать файлы (без модификации) с помошью MMF это нечто выдающееся, разве что "поиграться" :D
                                                                                                                          Матчасть учит, что в данном случае к бессмыленным потерям на отказы страниц при чтении мы добавляем столько же на отказы при записи + примерно столько же (если не больше) на копирование данных с места на место.
                                                                                                                          В приведенном коде лучше закомментировать FlushView и посмотреть, что будет с системой при копировании файла, превышающего размер ОЗУ. Тут даже точные измерения не нужны - достаточно включить системный монитор и понаблюдать за доступной памятью, обменом страниц и записью на диск. Ну и затем посмотреть как будет вести себя система после такого стресса - пооткрывать папки, программы, документы.

                                                                                                                          PS: Да, кстати, ты просил привести хоть один официальный источник, пиарящий чудесный супербыстрый MMF. Загляни в MSDN: Platform SDK разделы File Mapping и Improving Application Performance, выпиши на бумажку и заучи фразы: "Adwantages of File Mapping", "major adwantages", "Faster and easier file access", "access files more quickly and easily", "improves efficiency", "improve general system performance" (и это как раз в отношении отложенной записи !), ну и наконец откровенное лукавство "Using memory-mapped files for sequential file access is faster than standard sequential file access". После заучивания, можно вместе с другими попугаями повторять эти фразы до посинения :D Ну а упрямые факты и цифры для попугаев это ес-но туфта - происки Касперского и "не то" состояние системы на момент тестов :D
                                                                                                                            Цитата leo @
                                                                                                                            Интересно, почему ты при создании dst не задаешь flags как в src ?

                                                                                                                            А зачем? Ну поставлю теже флаги и на dst днем...
                                                                                                                              Цитата leo @
                                                                                                                              Просто копировать файлы (без модификации) с помошью MMF это нечто выдающееся, разве что "поиграться"

                                                                                                                              Для этого и давалось.

                                                                                                                              Цитата leo @
                                                                                                                              В приведенном коде лучше закомментировать FlushView и посмотреть, что будет с системой при копировании файла, превышающего размер ОЗУ. Тут даже точные измерения не нужны - достаточно включить системный монитор и понаблюдать за доступной памятью, обменом страниц и записью на диск. Ну и затем посмотреть как будет вести себя система после такого стресса - пооткрывать папки, программы, документы.

                                                                                                                              Чудес не бывает, поэтому и реальная запись на диск будет производится тогда, когда системе будет выгодно это сделать. Со всеми вытикающими занятиями ресурсов для этой операции.

                                                                                                                              Цитата leo @
                                                                                                                              PS: Да, кстати, ты просил привести хоть один официальный источник, пиарящий чудесный супербыстрый MMF. Загляни в MSDN: Platform SDK разделы File Mapping и Improving Application Performance, выпиши на бумажку и заучи фразы: "Adwantages of File Mapping", "major adwantages", "Faster and easier file access", "access files more quickly and easily", "improves efficiency", "improve general system performance" (и это как раз в отношении отложенной записи !), ну и наконец откровенное лукавство "Using memory-mapped files for sequential file access is faster than standard sequential file access".

                                                                                                                              Извини, но то, что ты надёргал встретившиеся знакомые фразы из контекста описания технологии, говорит о тебе, как о полном профане. Возможно, чтоб понимать о чем собственно пишется, тебе стоит немного подучить тот язык, на котором изложено описание.

                                                                                                                              ЗЫ. На "грязное" обращение лень отвечать, это можешь и без меня делать, перед зеркалом... :lool:
                                                                                                                                Указал флаг и для hWiler .. скорость поднялась еще на 10-12% .. вечером выложу все результаты.. и для mmap тоже..
                                                                                                                                  LuckLess, у меня твоя прожка выдает следующие результаты (после правки флагов для hFilew). Ну и я переставил порядок тестов по нарастающей размера буфера.

                                                                                                                                  ExpandedWrap disabled
                                                                                                                                    4KB  NB 100.5
                                                                                                                                    32KB NB 49.344
                                                                                                                                    64KB NB 42.688
                                                                                                                                    4MB  NB 38.109
                                                                                                                                    32MB NB 31.953
                                                                                                                                    32MB B 93.672


                                                                                                                                  Samsung SP2004C (SATA2), партиция NTFS. Файл 687Мб.

                                                                                                                                  Так что...
                                                                                                                                    Цитата Uncle_Bob @
                                                                                                                                    Samsung SP2004C (SATA2), партиция NTFS. Файл 687Мб.

                                                                                                                                    Так что...

                                                                                                                                    Почто идентичный результат (учитывая что у меня САТА2 рейд .. поэтому побустрее..)
                                                                                                                                    да, чем больше буффер, тем быстрее.
                                                                                                                                    Буфферизация дает страаашный тормоз(особенно буферизация файла - который копируем).
                                                                                                                                      LuckLess,

                                                                                                                                      ну на самом деле FILE_FLAG_SEQUENTIAL_SCAN не так и портит картину...

                                                                                                                                      ExpandedWrap disabled
                                                                                                                                        4KB  B  49.219
                                                                                                                                        4KB  NB 97.984
                                                                                                                                         
                                                                                                                                        32KB B  56.438
                                                                                                                                        32KB NB 50
                                                                                                                                         
                                                                                                                                        64KB B  41.016
                                                                                                                                        64KB NB 41.484
                                                                                                                                         
                                                                                                                                        4MB  B  161.578
                                                                                                                                        4MB  NB 38.422
                                                                                                                                         
                                                                                                                                        32MB B  102.016
                                                                                                                                        32MB NB 32.469
                                                                                                                                         
                                                                                                                                        64MB B  56.422
                                                                                                                                        64MB NB 0.046 // не катит
                                                                                                                                        Цитата Uncle_Bob @
                                                                                                                                        4KB B 49.219
                                                                                                                                        4KB NB 97.984

                                                                                                                                        32KB B 56.438
                                                                                                                                        32KB NB 50

                                                                                                                                        64KB B 41.016
                                                                                                                                        64KB NB 41.484

                                                                                                                                        4MB B 161.578 // Очень странная цифра
                                                                                                                                        4MB NB 38.422

                                                                                                                                        32MB B 102.016 // Очень странная цифра
                                                                                                                                        32MB NB 32.469

                                                                                                                                        64MB B 56.422
                                                                                                                                        64MB NB 0.046 // не катит


                                                                                                                                        Гм. Для больших буфферов FILE_FLAG_SEQUENTIAL_SCAN что, - замедляет?
                                                                                                                                          Цитата LuckLess @
                                                                                                                                          Гм. Для больших буфферов FILE_FLAG_SEQUENTIAL_SCAN что, - замедляет?

                                                                                                                                          Попробуй у себя.
                                                                                                                                            Да нет, я думаю все в пределах допустимой погрешности, т.к. на больших файлах FILE_FLAG_SEQUENTIAL_SCAN практически не должен влиять на результаты. Если верить MSDN и статейкам, то этот флаг - является лишь хинтом-подсказкой для ОС на начальном этапе чтения\записи, а затем она сама распознает последовательный доступ, если даже этот флаг не был установлен
                                                                                                                                            Сообщение отредактировано: leo -
                                                                                                                                              Цитата Uncle_Bob @
                                                                                                                                              Попробуй у себя.

                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                   std::cout << "4KB NB " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 4*1024) << "\n"; //46
                                                                                                                                                   std::cout << "4KB NB SS " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 4*1024,FILE_FLAG_SEQUENTIAL_SCAN) << "\n"; //22.5
                                                                                                                                                   std::cout << "32MB NB " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 32*1024*1024) << "\n"; //18
                                                                                                                                                   std::cout << "32MB NB SS " <<  RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 32*1024*1024,FILE_FLAG_SEQUENTIAL_SCAN) << "\n"; //36

                                                                                                                                              :whistle: :wacko: :wacko:
                                                                                                                                                LuckLess
                                                                                                                                                Задавая FILE_FLAG_SEQUENTIAL_SCAN, ты отключаешь NO_BUFFERING и результаты получаются примерно такие же как для flags = 0
                                                                                                                                                  Цитата leo @
                                                                                                                                                  LuckLess
                                                                                                                                                  Задавая FILE_FLAG_SEQUENTIAL_SCAN, ты отключаешь NO_BUFFERING и результаты получаются примерно такие же как для flags = 0

                                                                                                                                                  std::cout << "4KB NB SS " << RWNBCopy ("E:\\file.avi", "E:\\file2.avi", 4*1024,FILE_FLAG_SEQUENTIAL_SCAN) << "\n"; //22.5
                                                                                                                                                  :wacko: :wacko: Фигасе - такиеже..

                                                                                                                                                  Добавлено
                                                                                                                                                  такое ощущение, что FILE_FLAG_SEQUENTIAL_SCAN оптимизирует систему для работы с малыми буфферами..
                                                                                                                                                    LuckLess
                                                                                                                                                    Я не понял с чем ты сравниваешь. Чего-то я твоих данных для 4К и flags = 0 вроде не видел. А что касается NO_BUF, так он и должен быть хуже при малых размерах буфера.
                                                                                                                                                    Сделай в одном проходе чередование flags = 0 и SEQUENTIAL при 4К, тогда будет видна разница и разброс
                                                                                                                                                      МОДЕРАТОРАМ
                                                                                                                                                      На мой взгляд, название темы выбрано неудачно.
                                                                                                                                                      Речь идет конкретно о копировании файлов, и MMF здесь выступает лишь как один из методов, наряду с обычными Read\WriteFile. Заостряя внимание на MMF мы опять негласно расширяем тему дискуссии, что может опять увести разговор в сторону голословных рассуждений и споров. Поэтому думаю лучше изменить название темы на прежнее или еще более конкретное, типа "Как быстрее копировать файлы" или т.п.
                                                                                                                                                        FILE_FLAG_SEQUENTIAL_SCAN дает прирост 11-13% на 4кб буффере в сравнении с просто копировании без флагов.
                                                                                                                                                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                                                        0 пользователей:


                                                                                                                                                        Рейтинг@Mail.ru
                                                                                                                                                        [ Script execution time: 0,2136 ]   [ 16 queries used ]   [ Generated: 22.02.26, 10:13 GMT ]