igor87 0 16 мая, 2010 Опубликовано 16 мая, 2010 · Жалоба Есть задача: принимать данные от аппаратуры программой1 и через файл передавать их в программу2. Действие происходит в Windows XP. При этом не устраивает скорость записи данных в файл. Передача осуществляется средствами WinAPI. Есть ли более быстрые способы передачи данных? Желательно минимальное изменение изменение кодов программ по причине того, что программу 1 и 2 делают разные люди. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 16 мая, 2010 Опубликовано 16 мая, 2010 · Жалоба Есть задача: принимать данные от аппаратуры программой1 и через файл передавать их в программу2. Действие происходит в Windows XP. При этом не устраивает скорость записи данных в файл. Передача осуществляется средствами WinAPI. Есть ли более быстрые способы передачи данных? Желательно минимальное изменение изменение кодов программ по причине того, что программу 1 и 2 делают разные люди. Даже средствами WinAPI скорость сильно зависит от того, записываете ли вы файл маленькими кусочками, или же большими блоками. Максимальная скорость получается, если писать блоками с размером, равным величине кластера на диске, отменив буферизацию. Т.е. здесь вы делаете такую буферизацию вручную. Ну, а самая медленная скорость получится, если писать функцией WriteFile() побайтно. А если нужен обмен между двумя программами на одном и том же компьютере, то надо открывать "виртуальные" файлы - файлы, отображаемые на память (при помощи функции API CreateFileMapping()). О том, как это делается, читайте тут - http://frolov-lib.ru/books/bsp/v27/ch1_1.htm Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
igor87 0 16 мая, 2010 Опубликовано 16 мая, 2010 · Жалоба Спасибо за ответ! Так как запись нужно вести в режиме реального времени, то при записи маленькими кусочками (не побайтно конечно) скорости не хватает, а если большими кусками, то не хватает только в те моменты, когда ведется запись в файл. Такой вывод сделан на основе того, что каждая запись в файл получается от аппаратуры с меткой времени. Сравнивая соседние метки можем вычислить время, которое информация провела в пути от железа до файла. информация от аппаратуры получается по запрсу программы только после того, как был обработан ответ на старый запрос. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 16 мая, 2010 Опубликовано 16 мая, 2010 · Жалоба Выбирайте что больше нравится из Interprocess Communications если переходить от записи/чтения файлов, то минимум изменений, вероятно, потребуется для механизма Pipes Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
igor87 0 22 мая, 2010 Опубликовано 22 мая, 2010 · Жалоба А если нужен обмен между двумя программами на одном и том же компьютере, то надо открывать "виртуальные" файлы - файлы, отображаемые на память (при помощи функции API CreateFileMapping()). О том, как это делается, читайте тут - http://frolov-lib.ru/books/bsp/v27/ch1_1.htm Попробовал сделать при помощи файлов, отображаемых на память.Вопрос: какого размера файл лучше всего загружать? Долго тестировал этот параметр. Смотрел время,затрачиваемое на запись в файл (при помощи QueryPerformanceCounter). У меня получилась линейная зависимость (чем меньше файл, тем быстрее он записывается).Это правильный вывод?Просто я слышал рекомендации на тему того, что файл должен быть выровнен по границе страницы памяти... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 22 мая, 2010 Опубликовано 22 мая, 2010 · Жалоба Вопрос: какого размера файл лучше всего загружать? Долго тестировал этот параметр. Смотрел время, затрачиваемое на запись в файл (при помощи QueryPerformanceCounter). У меня получилась линейная зависимость (чем меньше файл, тем быстрее он записывается). Это правильный вывод? Просто я слышал рекомендации на тему того, что файл должен быть выровнен по границе страницы памяти... Этого я не знаю, т.к. скорость передачи меня никогда не волновала. Но если можно провести прямой эксперимент, то это много лучше, чем слушать чужие рекомендации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Deka 0 28 мая, 2010 Опубликовано 28 мая, 2010 · Жалоба Можно попробовать сделать виртуальный диск и именно там расположить файл. Это позволит не переделывать программы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
baralgin 0 28 мая, 2010 Опубликовано 28 мая, 2010 · Жалоба Как выше советовали, можно использовать именованные каналы (named pipes), тогда программы смогут общатся даже в пределах сети. А писать и читать можно стандартными Read/WriteFile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 28 мая, 2010 Опубликовано 28 мая, 2010 · Жалоба Я не буду слишком категоричной, но в отношении механизма pipes у меня имеются опасения. Pipe - канал между приложениями, а потому быстро записывать в его можно будет только тогда, когда приложение-приемник более прожорливое, чем тот поток данных, который отправляется ему в рот. Если оно не будет успевать их проглатывать (усваивать), передача будет торомозить на функции WriteFile. А если там все-таки возможна буферизация, которая спасает от ситуации, когда скорость передачи выше, чем скорость приема (или приемник глотает не непрерывно, а порциями, между которыми пауза), то будет тот же самый вариант, что и файл, отраженный на память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 28 мая, 2010 Опубликовано 28 мая, 2010 · Жалоба Буферизация у пайпов конечно же есть. Собственно ту часть программы что пишет в файл вообще переписывать не нужно. Просто вместо CreateFile() вызывается CreatePipe(), а функциям записи/чтения всё равно что это за хэндл, файла или пайпа, для них это без разницы. Что же касается синхронизации то она будет нужна при любом методе передачи и преимущество пайпов как раз в том, что синхронизация там уже встроена и ничего специально делать не нужно, само всё работает. А размером буфера можно управлять. Опять же, для любого механизма при большой неравномерности потока нужен буфер побольше чтобы избежать приостановки пишущего процесса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kojevnikov 0 3 июня, 2010 Опубликовано 3 июня, 2010 · Жалоба Смотри в сторону API функций: CreateFileMapping, MapViewOfFile Скорость записи в файл получается очень приличная. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
igor87 0 4 июня, 2010 Опубликовано 4 июня, 2010 · Жалоба Можно попробовать сделать виртуальный диск и именно там расположить файл. Это позволит не переделывать программы. А как это можно сделать? По поводу CreatePipe, я читал, что все механизмы межпроцессного взаимодействия основаны на файлах отображаемых на память. И в пределе могут достигать скорости этого метода. Так что я пока остановился на файлах отображаемых в память. Вроде задержки уменшились, но возникла проблема того, что весь файл надо держать в памяти, а он может заполняться данными около часа.Там объем приличный может набегать. Я думал, что можно отображать часть файла, но похоже ошибся. Вот только память выделяется как-то не прямо пропорционально.То есть я вроде отображаю здоровый файл, а прибавка занимаемой памяти процессором маленькая.То есть механизм состоит не в том, что файл целиком находится в оперативной памяти, правильно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 5 июня, 2010 Опубликовано 5 июня, 2010 · Жалоба файл целиком находится в оперативной памяти, правильно? Под файл выделяется виртуальная память, которой не жалко. А реально существующая память будет выделяться только для тех участков файла в которые что-то писали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terrarium 0 7 июня, 2010 Опубликовано 7 июня, 2010 · Жалоба Вот только память выделяется как-то не прямо пропорционально.То есть я вроде отображаю здоровый файл, а прибавка занимаемой памяти процессором маленькая.То есть механизм состоит не в том, что файл целиком находится в оперативной памяти, правильно? Для обмена данными с помощью общей памяти используются три функции: CreateFile - собственно создаем начальный handle, который дублируем в другой программе, CreateFileMapping - задаем, какого размера у нас будет общая память MapViewOfFile - создаем "окно", в которое 1-й процесс пишет, 2-й - читает... Поэтому, Вы можете создать большое общее пространство, и, открывая в нем "окна" небольшого размера для записи, записав, уведомлять считывающую программу о готовности очередного окна. Программа-считыватель открывает окно, читает, посылает уведомление пишущей, та закрывает окно, и оперативная память для данного окна освобождается. Поэтому реально выделенный объем будет равен ровно тому объему, который уже записан, но еще не прочитан. Далее, организуется запись "по кругу", когда вы по достижении конца файла начинаете писать в его начало. Если вы читаете быстрее, чем пишете, получится стабильная система. Насчет страниц памяти тоже все верно, для современных интеловских процессоров размер страницы составляет 4 килобайта, на кратную величину и надо ориентироваться... Использование каналов, на мой взгляд, для данной задачи несколько удобнее, потому что вам не нужно заботиться о синхронизации - для случая с потоком, скажем, 1 мегабайт/с это вполне подойдет (если, конечно, приемник успевает "переварить" этот поток с точки зрения вычислительной трудоемкости). Кроме того, для ОС Линукс такой подход вообще стандартен - перенаправить вывод одной программы на ввод другой - например, результат поиска файлов на поиск шаблона имени а потом на программу сортировки. При этом вся буферизация/синхронизация ложится на ОС, и все работает очень эффективно - самому написать без вдумчивого анализа и большого опыта написания многопоточных программ вряд ли получится... Если же потоки горазбо больше - гигабитный Ethernet фильтровать, к примеру, то, как альтернативу, предлагаю рассмотреть возможность использования MPI - ru.wikipedia.org/wiki/MPI - он изначально создавался для больших вычислительных систем с интенсивным обменом данными между различными процессами/узлами кластеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
igor87 0 13 июня, 2010 Опубликовано 13 июня, 2010 · Жалоба А GetSystemInfo() говорит, что гранулярность памяти 64 Кбайта. Пока остановился на варианте с файлами оторбражаемыми на память. Работает и, предварительно, скорость устраивает. По поводу MPI. Спасибо за сведения! Если этот вариант не покатит - попробую! Всем спасибо! Пока все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться