Перейти к содержанию
    

CY7C680013A Киньте ссылкой на софт и лит-ру

В том и дело, что у меня как раз и получается 20 мб/сек в лучшем случае. Это при том, что чипсет как раз ICH5. Если не затруднит, помогите ускорить мое творение. Выкладываю все исходники включая GPIF проект (используются FIFOrd и FIFOwr, одиночные давно не использовал). Я не могу понять, что у меня неправильно написано.
Хм... На первый взгляд, вроде, все верно. Только я обратил бы внимание на функцию

 

DWORD WINAPI thread_usb_loop (void *data)

 

Мне представляется, что в ней блок вызовов

 

usb_begin_out_transfer(s_tex_orig, TEXTURE_WIDTH * TEXTURE_HEIGHT);

usb_begin_in_transfer(s_tex_processed, TEXTURE_WIDTH * TEXTURE_HEIGHT);

usb_wait_out_transfer_finish();

usb_wait_in_transfer_finish();

 

не совсем рационально использует CPU. Например, после выполнения операции OUT получается непроизводительная трата времени на ожидание операции IN. Наверное, стоило бы взглянуть на пример Streamer из Cypress'овской USB DevStudio. В этом примере рассматривается очень рациональный метод потокового выполнения заданий. Т.е. запускается сразу несколько операций считывания (в этом примере производится считывание данных в компьютер). В твоем примере, видимо, стоит сделать точно так же, но усложнить алгоритм, добавив в него еще и вывод кадров. Может быть, стоило бы сделать отдельные треды для вывода кадров и для их последующего ввода. Тогда степень распараллеливания может быть максимальной. Глубина очереди, IMHO, может быть на уровне примерно 4-х операций (т.е. число элементов в очереди операций). Также следует помнить о синхронизации вывода кадров и их последующего ввода в компьютер. Думаю, что тут можно применить что-то простенькое, типа счетчика, изменяемого в закрытой секции каждым потоком (тредом).

 

Ну и, наконец, думаю, что стоило бы поиграться величиной порций видео-данных, передаваемых туда и обратно. Может быть можно получить выигрыш в скорости за счет более плавной загрузки канала передачи, если передавать не весь кадр целиком, а разбить его на кусочки по 8-16-32 КБайт. Объяснить не могу, но закрадывается чувство, что работа драйвера с большими порциями данных на одну операцию может вызвать дополнительные накладные расходы. Впрочем, в этом вопросе я не силен, возможно этот мой взгляд ошибочен.

 

Кроме того, думаю, стоило бы прикинуть время выполнения операций, т.е. в треде вывода считать период выдачи кадров, а в треде ввода, соответственно, их считывания. Для чистоты эксперимента и получения наиболее точных значений производительности, стоило бы временно выключить операции OpenGL, чтобы получить чистые цифры самой передачи по USB. Для подсчета времени следует использовать максимально точный в Винде таймер QueryPerformanceCounter. Например я делаю так: накапливаю в сумматоре показания QueryPerformanceCounter и запоминаю число полученных пакетов, а затем раз в секунду (в основной виндовой программе) делю одно на другое, перевожу в секунды и вывожу на индикацию. Причем, тут следовало бы накапливать целый ряд сумматоров: период вывода, время очередного вывода, период ввода, время очередного ввода, и, может быть, еще какие-нибудь ключевые моменты алгоритма передачи данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне удалось достичь скорости 33МБайт\с на Bulk In на драйвере ezusb.sys, думаю можно поднять еще немного, переписав функцию драйвера приемопередачи. И поднять еще немного, увеличив скорость заполнения фифо (щас у меня примерно 36Мгц) до штатных 48Мгц. У меня другая проблема, хочу сказать драйверу (один раз), получи-ка асинхронно эти 33МБ вот в этот буфер, а когда получишь, дерни рабочий поток, чтоб обработал. Так вот беда в том, что пока драйвер будет получать эти 33МБ (примерно сек) ОС замрет на это время, а это не есть гуд...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне удалось достичь скорости 33МБайт\с на Bulk In на драйвере ezusb.sys, думаю можно поднять еще немного, переписав функцию драйвера приемопередачи.
Здорово! А ты взял стандартный драйвер ezusb.sys, или "доработал его напильником"? Интересно, как он в сравнении с CyUsb.sys? А что нужно переписать в функции приемопередачи драйвера? (Я с драйверами еще не ковырялся, они мне представляются этакими страшными, таинственными и очень сложными монстрами :-) )

 

У меня другая проблема, хочу сказать драйверу (один раз), получи-ка асинхронно эти 33МБ вот в этот буфер, а когда получишь, дерни рабочий поток, чтоб обработал. Так вот беда в том, что пока драйвер будет получать эти 33МБ (примерно сек) ОС замрет на это время, а это не есть гуд...
Да... Похоже, что следует, все-таки, разбивать большой объем передачи на относительно небольшие кусочки. Тогда и ОС не будет притормаживать, и другие задачи смогут выполняться более-менее нормально (хотя полностью "прозрачно", конечно, не будет, больно уж скорость передачи здоровая, это неизбежно должно немного чувствоваться).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2jur

Я взял стандарнтый ezusb.sys. Про CyUsb.sys не знаю, не пробовал, но думаю что выигрыша уже не будет. Так как исходников его нету, а я его ставил как-то раз, то могу предположить, что код, ответственный за приемопередачу, врядли короче и чище чем у ezusb.sys. Поверхностно они отличаются способом создания устройства. ezusb.sys создает устройство "EZUSB-0" а CyUsb.sys действует через GUID.

Много доработать не получится, так как там все просто и "лишних" вызовов на чем можно съэкономить почти нет. Доработка заключается в увеличении входного буфера, в оригинале драйвер принимает не больше 2^16 байт за раз, но у меня максимальная скорость была при 2^15. Так вот, чтобы получить 33Мега надо 1024 раза вызвать драйвер с буфером 2^15. А это "лишние" накладные расходы. Да и прога будет заниматься только тем что вызывать драйвер и ждать пока придет очередная порция, а обрабатывать будет некогда. Вот тогда и родился вариант отдать драйверу весь буфер 33МБ, и когда он заполнится, взведется событие, по которому аппилуха обработает данные.

Изменено пользователем Warlord

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доработка заключается в увеличении входного буфера, в оригинале драйвер принимает не больше 2^16 байт за раз, но у меня максимальная скорость была при 2^15.
Большое спасибо за разъяснение!

 

Так вот, чтобы получить 33Мега надо 1024 раза вызвать драйвер с буфером 2^15. А это "лишние" накладные расходы. Да и прога будет заниматься только тем что вызывать драйвер и ждать пока придет очередная порция, а обрабатывать будет некогда. Вот тогда и родился вариант отдать драйверу весь буфер 33МБ, и когда он заполнится, взведется событие, по которому аппилуха обработает данные.
Хм... Снова на ум приходит все тот же пример Streamer из Cypress'овской USB DevStudio. Взгляни, там очередь заданий запускается вот таким образом:

 

// Queue-up the first batch of transfer requests

for (i=0; i< QueueSize; i++) contexts = dlg->InEndPt->BeginDataXfer(buffers, len, &inOvLap);

 

Из этого примера видно, что происходит выполнение следующего приема данных параллельно с их обработкой в прикладной программе, т.е. получили данные из первого запроса (и снова перезапустили, чтобы очередь была постоянно заполненна) и можем их обрабатывать, а драйвер тем временем качает дальше. Я пробовал поиграться параметрами такого запуска на слабенькой embedded-материнке (VIA EPIA SP, PIII 1.3 GHz, 17 x 17 cm) и получил хорошие показатели сбалансированности нагрузки при 4-х запросах в очереди и 8 блоках в каждом запросе (т.е. порция данных 4 КБ). Может быть и в твоем случае можно применить похожий механизм? Тогда не нужно будет организовывать такой большой буфер в драйвере. Ведь в этом случае получится хорошее распараллеливание процесса: драйвер порции данных качает, а приложение их обрабатывает по мере поступления. Хотя я на таких больших скоростях не работал, возможно мои рассуждения ошибочны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, щас сам глянул CyUSB.sys и увидел, что этот драйверок намного навороченнее чем ezusb.sys. Там и потоки запускаются, и события сбрасываются\устанавливаются и еще много чего интересного делается. А потом я глянул Streamer и похоже что так оно и есть, порциями работа, щас гляну поподробнее как это функционирует. Очень даже может быть это и есть, то чего исчу :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне удалось достичь скорости 33МБайт\с ...думаю можно поднять еще немного, переписав функцию драйвера приемопередачи.... И поднять еще немного, увеличив скорость заполнения фифо ...

 

...прошу прощения, что встрял в обсуждение...

 

А на какую максимальную скорость можно расчитывать для случая непрерывного потока данных в одну сторону (из устройства в компьютер)?

т.е. достиг ли кто нибудь скорости в 40МБайт в сек в случае передачи данных в течении, например, 1часа (144Гбайта) абсолютно без потерь данных?...

это про ХХ68013..., хотя, и не обязятельно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А на какую максимальную скорость можно расчитывать для случая непрерывного потока данных в одну сторону (из устройства в компьютер)?
IMHO, очень много от чего зависит. От железа, драйверов, прикладной программы, операционки, наконец. Судя по опыту коллеги Warlord, похоже, что скорость в 40 МБайт/сек достижима (хотя это и нелегко).

 

т.е. достиг ли кто нибудь скорости в 40МБайт в сек в случае передачи данных в течении, например, 1часа (144Гбайта) абсолютно без потерь данных?...
Без потерь данных - лёгко :-) Bulk endpoint обеспечивает безошибочную передачу. (Правда, в условиях сильных помех, при наличии ошибок передачи, упадет скорость, т.к. "булки" обеспечивают гарантированную доставку данных, но при этом идут перезапросы, т.е. не гарантируется траффик.)

 

Интересно, также, как работают Interrupt endpoints? Они ведь тоже гарантируют доставку, но еще и позволяют задавать время опроса. Т.е. и без ошибок и быстро. (?)

 

2 All. Просветите, пожалуйста, кто знает, чем хороши/плохи Interrupt endpoints? Может быть эти каналы позволяют сочетать скорость и надежность? (Согласно спецификации USB 2.0 скорость Interrupt endpoints такая же, как и Bulk endpoints, хотя это и напоминает бесплатный сыр...)

 

А количество данных... Если данные не нужно запоминать (вроде видеостриминга какого-нибудь), то передавай хоть терабайты :-) И ни один байт никуда не денется, если по Bulk или Interrupt...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... похоже, что скорость в 40 МБайт/сек достижима (хотя это и нелегко).

 

Теоретически... - это понятно...

Вопрос в практической реализации...

 

2 ALL... похвастайтесь...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера примерялся к драйверку CyUSB.sys а сегодня утром получил свежие данные касательно скорости. Драйверок-то действительно побыстрее ezusb.sys будет :) Мне удалось принять от железки 37МБ за 1000мс, т.е. за секунду. Это на 4МБ больше нежели с ezusb.sys. Причем прием асинхронный, что особенно радостно, огромное спасибо jur за инфу о Streamer. Об Interrupt Endpoints знаю немного, знаю что используются если устройство принадлежит к HID-классу, тогда родной драйверок виндофс САМ будет опрашивать и забирать данные с Endpoint-а, а аппликухе остается только забрать их у драйвера. Смущает только одно: параметр bInterval если он =1 то опрос проводится драйвером каждую 1мс даже при HI-speed. А это не есть гуд, поскольку очень редко, если размер Endpoint 1024 то терия дает всего 1МБ.. Возможно я заблуждаюсь и буду рад, если знающий поправит :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера примерялся к драйверку CyUSB.sys а сегодня утром получил свежие данные касательно скорости. Драйверок-то действительно побыстрее ezusb.sys будет :)
Мне он тоже как-то сразу понравился :-) Правда, повлияло еще и то, что в ходе общения со службой техподдержки Cypress'а они мне объяснили, что ezusb.sys хорош для обучения и как основа для разработки своего драйвера. А CyUsb.sys - это коммерческое изделие, годящееся для серийной продукции. Т.к. у меня нет опыта разработки драйверов под Винду, а драйвер CyUsb.sys авторы разрешают использовать совершенно бесплатно, то я на него и "запал". А уж когда я убедился, что по сравнению с драйверами от FTDI этот драйвер отличается еще и превосходной стабильностью, то мой выбор сузился до единственного варианта :-)

 

... огромное спасибо jur за инфу о Streamer.
Всегда пожалуйста! Мы ведь тут именно для этого и обитаем, для общения и взаимопомощи :-)

 

Смущает только одно: параметр bInterval если он =1 то опрос проводится драйвером каждую 1мс даже при HI-speed. А это не есть гуд, поскольку очень редко, если размер Endpoint 1024 то терия дает всего 1МБ.
Нет, это не так. Вот что сказано в разделе "5.7.4 Interrupt Transfer Bus Access Constraints" спецификации шины USB 2.0 (стр. 51):

 

High-speed endpoints can specify a desired period (2^bInterval-1)x125 µs, where bInterval is in the range 1 to (including) 16. The USB System Software will use this information during configuration to determine a period that can be sustained. The period provided by the system may be shorter than that desired by the device up to the shortest period defined by the USB (125 µs microframe or 1 ms frame).

 

Кроме того, в таблице 5-8 (на той же стр. 51) указаны цифры максимальных скоростей, которые такие же, как и для "булки".

 

Я так понял, что для High-speed ендпойнты период опроса может быть вплоть до 125 мксек. Кроме того, за один микрофрейм можно передавать еще и несколько пакетов (до трех штук вроде). В общем, интересная вещь, эти interrupt endpoints. Жаль, что пока очень непонятная...

 

P.S. У меня появилась одна мысль. Может быть ты можешь провести опыт? Попробуй, пожалуйста, сменить конфигурацию своей endpoint'ы с Bulk на Interrupt (с bInterval = 1) и запустить высокоскоростную передачу. Очень интересно было бы сравнить эти два канала. Какова максимальная скорость передачи? Насколько сильно при этом нагружается процессор? Чем вообще похожи/отличаются эти два вида ендпойнтов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Провел я опыт, результаты - 37МБ за 9.4сек, т.е. почти в 10 раз медлененнее. Загрузка проца 10-8-7-5-4-10-0 (P4-2800). Все параметры перепроверил EP bAttributes 0x03 bInterval=0x01, все как надо, девайс говорит - HiSpeed, использую CCyInterruptEndPoint, все как доктор прописал, но увы, что-то не срастается...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Провел я опыт, результаты - 37МБ за 9.4сек, т.е. почти в 10 раз медлененнее. Загрузка проца 10-8-7-5-4-10-0 (P4-2800).
Большое тебе спасибо за информацию! Очень интересно! Теперь видно, что Bulk и Interrupt ендпойнты чем-то отличаются. Причем, судя по результатам твоего опыта, отличаются существенно. Однако, при чтении спецификации на USB 2.0 это различие как-то не бросается в глаза... Черт... Придется углубиться в вопрос...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тут главное понять для чего вообще нужен это тип EP, немного странно, что у Cypress нет ни одного примера с использованием такого EP. Единственное применение, которое я нашел и реализовал - это HID устройство, виндовый драйвер которого HIDUsb.sys сам опрашивает железяку, а мне оставалось только забирать данные через ReadFile.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привет!

 

Провел некоторые эксперименты (P4, 3.06 GHz). Я сделал модификацию фирмваре FX2 так, чтобы она постоянно передавала блок данных (там просто мусор, сами данные неважны, передается просто 512 байт). А на компьютерной стороне я применил пример Streamer, который обращается к драйверу, получает данные и ничего с ними не делает, просто считает скорость передачи. Пробовал на двух одинаковых компьютерах. На первом установлена память DDR333. Скорость передачи была порядка 37.5 МБайт/сек. Точно такая же, какую получил в своих опытах коллега Warlord. А на втором установлена память DDR400. При этом скорость передачи возросла почти до 40 тысяч МБайт/сек. Вот скриншоты со второго компьютера:

 

streamer016pkts6ol.pngstreamer064pkts6np.png

 

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

 

Однако, выплыл ньюанс, гробящий на корню мою быструю передачу. После примерно полутора минут передачи скорость падает больше чем на порядок и дальше болтается у этой очень небольшой величины. Что бы это могло значить? Вот поясняющие скриншоты:

 

streamer256x8pkts13yq.pngstreamer256x8pkts20hz.png

 

Также я заметил, что при запуске приложения появляется тонкий свист из компьютерного блока, похожий на свист импульсного источника питания при существенном возрастании нагрузки. Особенно громкий свист был при условиях, показанных на самом первом скриншоте.

 

Предварительный (еще очень ранний) вывод: скорость под 40 МБайт/сек простыми методами недостижима. Коллеги, очень прошу, поделитесь, не сталкивались ли вы с подобными эффектами? Особенно настораживает падение скорости передачи после полутора минут (!) после начала передачи.

 

Coming soon. Сейчас готовлюсь пойти по стопам коллеги Warlord в направлении Interrupt endpoints :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...