LINUX.ORG.RU

быстрая пересылка данных

 , ,


0

2

Всех приветствую.
Щас вот потихоньку ваяю некую систему по передачи данных из одной железки в другую, а потом забор от второй железки для отображения в «реалтайме» на монике.
В силу специфики приходится использовать определенные решения на которые повлиять я не в силах. Поэтому хочется сделать быстро и красиво из того что есть.
Немного про компоненты.
1. Железяка которая по DMA через PCI мне шлет кучу данных (все обмазано кучей драйверов и библ на Scatter/Gather и прочее). В итоге я имею в оперативе буфер куда все сливается. Приложение для приема данных пишу я сам, так что могу изгаляться как угодно.
2. другая железяка, в которой куча DSP-ядер, которая на входе получает файл, из него все читает и выплевывает результат в другой файл.

Хочется как-то данные из моего буфера быстро и не напряжно завернуть так чтобы вторая железяка думала, что читает из своего файла, а на самом деле из моего буфера. Первые мысли это конечно придумать именованный FIFO. Но возникает вопрос как в него быстро передавать мой буфер. Потому как буфер в котором я получу данные от железки1 где-то в ядре. И мне (если я правильно понял) копируется в юзерспейс, а запись в FIFO это опять копирование из юзерспейса обратно в ядро. Хочется сделать это все как-нидь без лишних движение. В принципе все исходники всех библ, драйверов и утилит у меня есть. По большому счету вопрос в том как отобразить буфер в системной памяти на FIFO, чтобы запись в этот буфер сразу приводило к заполнению этого FIFO. Надеюсь не слишком сумбурно.

★★★★★

Надеюсь не слишком сумбурно

не надейся.

MKuznetsov ★★★★★
()

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

joy4eg ★★★★★
()
Ответ на: комментарий от joy4eg

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

Для всего исходники есть, но сильно курочить эти приложения желания нет. Условно, можно слегка поправить правила открытия файлов в приложении для ж2 чтобы можно было открывать FIFO (хотя по итогам эксперимента он и так отлично открывается). Подозреваю, что достаточно будет в моем приложении для ж1 открыть уже готовый FIFO и туда пихать данные. И с учетом того что там жирный i7 производительности и так хватит. Но хотелось бы сделать покрасивше.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от ebantrop

Как ДМА ж1 сделан?

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

Ж2 тоже по ДМА забирает или в неё впихивают?

Тут вопрос сложней. Наверняка не скажу. Но исходя из того, что все библиотеки, драйвера и утилиты написаны одним производителем, то скорей всего там тоже ДМА. Просто весь обмен с внешним миром происходит через FIFO (аппаратный внутре железки) так-что заманчиво использовать ДМА по половинному опустошению.

Я кажется понял к чему вы клоните, запилить ДМА канал так, чтобы происходило прямое копирование из одной железки в другую. Я об этом с самого начала думал, но, но есть подозрение, что предоставленное ПО таким свойством не обладает, а влазить в их архитектуру для того чтобы внедрить туда еще один способ обмена довольно затратен по временным ресурсам. С другой стороны можно наверно у автора спросить, может что подскажет.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от dimon555

почитай про RDMA

Чтиво занятное, но немного не то. У меня один комп, в нем есть пара железок, пара драйверов, библиотеки и приложения. Хочется передавать данные из одной железки в другую с минимальным расходом ресурсов (передавать надо много и без задержек).

yax123 ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Используй прямой обмен между PCI-устройствами.

это следующий этап, возможно и не достижимый.

сейчас интересней узнать про mmap на FIFO

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

сейчас интересней узнать про mmap на FIFO

Ты не можешь сделать mmap на FIFO, но нет никаких проблем замапить юзерспейсу именно те страницы, которые только что заполнены через DMA (замапить без копирования); точно так же нет никаких проблем замапить именно те страницы, которые ты собираешься передать на устройство через DMA. Поток сознания в хедпосте я не осилил, так что даже не понимаю, как ты умудрился добиться копирования данных при mmap.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от yax123

mmap - может отобразить FIFO в память?

Да я, если честно, не знаю. Попробуй. Вообще, должна же быть в нормальной операционной системе функция представления куска памяти как файла.

anonymous
()
Ответ на: комментарий от tailgunner

как ты умудрился добиться копирования данных при mmap.

я еще ничего не умудрился. Я пока еще отвлеченно рассуждаю.
Задача стоит такая. Из одной железяки (ж1) по дма переложить поток данных в файл, который читает некий второй процесс (п2) и передает в другую железяку (ж2).
логику работы п2 менять не можем. У него внутре есть open(f) и в цикле он делает read(f,buff,size_buff). Из-за того, что read блокирующий, пока он не прочтет sizebuff он сидит и ждет. Заменяем ему обычный файл на файл-fifo и получаем возможность порциями (по size_buff) подкладывать ему данные (он эти порции будет с удовольствием употреблять). Осталось как-то этот fifo-файл заполнять так чтобы избежать лишних телодвижений.

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

Понятно, что напрямую отобразит fifo в память невозможно (fifo не имеет размера). Но возможно есть какой-то механизм, который позволяет входной конец fifo «подключать» к разным буферам, в результате чего в fifo «как бы» будут появляться данные размера подключенного буфера. Тут конечно в полный рост встает вопрос синхронизации (когда можно к входному концу fifo подключить следующий заполненный блок). Но ради такой синхронизации я готов залезть в исходники п2 и добавить какой-нидь сигнальный костыль.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Ну-ка, глянь-ка тут. Вероятно это то, что ты хочешь.

*поглаживая уютный зеленый томик Стивенса «Unix: взаимодействие процессов»
Думаю это совершенно не то.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

От имени и по поручению КО я скажу следующее:

  • нижний уровень драйвера читает и пишет набор страниц (SG у тебя есть)
  • верхний уровень драйвера сигналит ждущему процессу о наличии данных через обычный poll (готовность дескриптора к чтению)
  • верхний же уровень отображает заполненные данными страницы по запросу юзерспейса
  • юзерспейс что-то делает с этими данными и вызывает munmap
  • драйвер выдает (возможно, модифицированный) набор страниц на другое устройство

Фактически, драйвер управляет двумя железками (платой снятия данных и платой для их обработки), а блокирующая операции read заменяется на poll + mmap; естественно, наборов страниц может быть несколько (скажем, 3 - один читается с платы сбора данных, второй обрабатывается юзерспейсом, третий пишется на плату обработки).

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

От имени и по поручению КО я скажу следующее:

Передайте КО, чтобы он перечитал все что я писал.
Если бы у меня было желание (а у меня его нет) и возможность (времени на это тратить точно нет) запилить свой драйвер для двух железяк сразу, то я бы и сам мог побыть в его роли. А пока мне нужно в файловый дескриптор некой проги волшебным образом подсовывать свои данные. Так что передайте КО, чтобы он отвечал на поставленный вопрос, а не на вопрос на который ему хочется ответить чтобы подтвердить свое звание.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Передайте КО, чтобы он перечитал все что я писал.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

было невозможно понять.

Согласен, что без контекста, некоторые вещи не очевидны, тем не менее это не оправдание для ответа на вопросы которые не задавались.
Я уже 2-3 раза сформулировал желаемое. В целом, в последнем моем сообщении в конце уже сказано, что хочется получить.
Просто, возможно есть еще какое-то решение, которое можно реализовать имея исходники всех компонентов.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

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

Когда человек готов потратить некоторые силы на то, чтобы понять вопрос, он не должен за это оправдываться.

В целом, в последнем моем сообщении в конце уже сказано, что хочется получить.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Когда человек готов потратить некоторые силы на то, чтобы понять вопрос, он не должен за это оправдываться.

Готов подписаться под каждой буквой. Но сам увидел лишь, неудачную попытку разобраться и вместо того чтобы хотя бы признать, что не разобрался (по моей вине), придумывать решение задачи для других условий.

уровни абстракции всё так же перемешаны

Вместо того чтобы об это спотыкаться, может задуматься о том для чего это было сделано?

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Не понял вопроса? Сделан как обычно.

Есть много способов реализовать ДМА. Зависит от железки и драйвера. Есть в ядре какой-то DMA API, но я им не пользуюсь поскольку данных много очень. В этом апи есть быстрые аллокаторы, которые можно прям из обработчика прерывания вызывать, но потом эту память надо вернуть, что мне не подходит.

RDMA реализовать, как тут многие советуют, не пенис канина, если не иметь доступа к спецификации железок. Даже если и иметь, может тупо не покатить поскольку у железок нет памяти и все идёт через ЦПУ.

ebantrop
()
Ответ на: комментарий от ebantrop

Есть в ядре какой-то DMA API, но я им не пользуюсь поскольку данных много очень. В этом апи есть быстрые аллокаторы, которые можно прям из обработчика прерывания вызывать, но потом эту память надо вернуть,

Ы? DMA API ядра не выделяют память, а мапят ее для DMA. Возвращать память не нужно, можно хоть всю системную память заполнить.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Да, таки я неправ. Оно маппит то что kmalloc даёт. Может что-то ещё можно замапить, я не особо разбирался и написал свой велосипед который через get_user_pages пинит юзерспейсовую память, которой я выделяю много и сразу.

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

ebantrop
()
Ответ на: комментарий от ebantrop

если не иметь доступа к спецификации железок.

Железяки это плисины. Доступны исходники. Что-то уже написано поставщиками драйверов и библиотек, что-то мы свое дописываем.

Насчет ДМА тут есть один скользкий вопрос, который я для себя еще не прояснил. С одной стороны постулируется наличие ДМА, с другой устройство в адресном пространстве представлено так, что ДМА там особо и не запустишь.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Железяки это плисины. Доступны исходники.

Тогда вообще не проблема глянуть что да как.

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

Это как??

ebantrop
()
Ответ на: комментарий от ebantrop

Тогда вообще не проблема глянуть что да как.

Глянуть то можно, вот только поймешь ли? Исходники ядра тоже можно смотреть. Много ли пограмистов с ходу напишут приличный патч?

Это как??

Авторы прояснили, все нормально. У них все оказалось несколько сложней, чем я думал.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Глянуть то можно, вот только поймешь ли? Исходники ядра тоже можно смотреть. Много ли пограмистов с ходу напишут приличный патч?

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

По сути топика для начала я бы сделал просто кольцевой буфер в памяти с прибитыми страницами. Отдал бы его на заливку Ж1 и написал бы драйвер, который эмулирует ФИФО из этого буфера. Если у Ж2 тоже есть ДМА на засос данных к себе, то можно ему скормить адреса прибитых страниц и все. Если делать совсем кошерно с RDMA PCIe-PCIe без основной памяти, то нужно смотреть как быстро Ж2 может кушать данные и как именно она их потребляет, также следить не переполнится ли чего у Ж1.

ebantrop
()
Ответ на: комментарий от ebantrop

По мне наличие исходников сильно облегчает работу, когда нужно понять что аффтары имели ввиду в документации

Сложно спорить с очевидным. Хотя данный вид исходников отличается замудренностью с одной стороны и неряшливостью с другой. Это не референс-дизайн, а наколенная поделка (но из сложной и стройной иерархии объектов) для решения посторонних задач (тестирования ж1).

Если делать совсем кошерно с RDMA PCIe-PCIe без основной памяти

А зачем тут RDMA? Этот же фокус только для доступа к памяти другого компа. У меня две железки воткнуты в один комп. Нужно просто вторую железку «разместить» в памяти и все. Но в любом случае это не то. Лезть в работающую железку влом. Тем более писать драйвер и т.д. Гораздо интересней это замутить с FIFO-файлом. Похоже можно просто в write(fd_fifo, buf,size_buf) подсовывать куски моего буфера и этого уже будет достаточно (как я понимаю принимающая сторона будет реально из этого буфера и читать).

yax123 ★★★★★
() автор топика

И мне (если я правильно понял) копируется в юзерспейс, а запись в FIFO это опять копирование из юзерспейса обратно в ядро. Хочется сделать это все как-нидь без лишних движение.

Обоснуй, на кой оно тебе сдалось, преемнику подгадить? Копируй в userspace и обратно, «реалтайм» же у тебя в кавычках.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

«реалтайм» же у тебя в кавычках.

мне нужно гарантированно раз в 16 мс передать около 0,16 мегабайта. Если есть затык то очередную передачу можно и «выкинуть» (это не принципиально).

преемнику подгадить?

по себе небось судите?

Обоснуй, на кой оно тебе сдалось,

Зачем мне что-то обосновывать? Понятно, что как-нидь я все это сделаю. И скорей всего это все будет работать. Еще мне тут пришло на ум, что:

а запись в FIFO это опять копирование из юзерспейса обратно в ядро

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

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

мне нужно гарантированно раз в 16 мс передать около 0,16 мегабайта. Если есть затык то очередную передачу можно и «выкинуть» (это не принципиально).

звучит вменяемо для userspace. jack же может.

преемнику подгадить?

по себе небось судите?

нет, в догадках теряюсь.

Понятно, что как-нидь я все это сделаю.

То есть «разумно и просто» не надо? Ну ок.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

То есть «разумно и просто» не надо? Ну ок.

Разумно и просто в моих условиях, а не в вымышленных ваших. А то я знаю любимую ЛОР-игру, решать не поставленную задачу, а задачу которую хочется решить.

В целом, для себя я уже уяснил что и как делать, тред можно закрывать. Любопытно правда почитать как работает в системе механизм pipe/fifo, чтобы просто и доходчиво было написано.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

А то я знаю любимую ЛОР-игру, решать не поставленную задачу, а задачу которую хочется решить.

Всю игру запортил.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Всю игру запортил.

Мой тред и я тут играюсь как нравится мне.

yax123 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.