Jump to content

    

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 и запоминаю число полученных пакетов, а затем раз в секунду (в основной виндовой программе) делю одно на другое, перевожу в секунды и вывожу на индикацию. Причем, тут следовало бы накапливать целый ряд сумматоров: период вывода, время очередного вывода, период ввода, время очередного ввода, и, может быть, еще какие-нибудь ключевые моменты алгоритма передачи данных.

Share this post


Link to post
Share on other sites

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

Share this post


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

 

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

Share this post


Link to post
Share on other sites

2jur

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

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

Edited by Warlord

Share this post


Link to post
Share on other sites
Доработка заключается в увеличении входного буфера, в оригинале драйвер принимает не больше 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 КБ). Может быть и в твоем случае можно применить похожий механизм? Тогда не нужно будет организовывать такой большой буфер в драйвере. Ведь в этом случае получится хорошее распараллеливание процесса: драйвер порции данных качает, а приложение их обрабатывает по мере поступления. Хотя я на таких больших скоростях не работал, возможно мои рассуждения ошибочны.

Share this post


Link to post
Share on other sites

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

Share this post


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

 

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

 

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

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

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

Share this post


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

 

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

 

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

 

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

 

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

Share this post


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

 

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

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

 

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Вчера примерялся к драйверку 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) и запустить высокоскоростную передачу. Очень интересно было бы сравнить эти два канала. Какова максимальная скорость передачи? Насколько сильно при этом нагружается процессор? Чем вообще похожи/отличаются эти два вида ендпойнтов?

Share this post


Link to post
Share on other sites

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

Share this post


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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Привет!

 

Провел некоторые эксперименты (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 :-)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this