|
Как повысить скорость работы по сети AT91SAM7X256 |
|
|
|
Apr 22 2008, 07:21
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 5-12-06
Пользователь №: 23 146

|
Некоторое время назад я разрабатывал прошивку для этого процесора в которой была добавлена функциональность обмена данными по сети и USB. В качестве операционной системы использована FreeRTOS, TCP/IP стека - uIP. Сейчас потребовалось повысить скорость обработки событий устройством и оказалось, что по сети обмен данными идёт медленно. Так как я разбирался со всеми нюансами процесора и внутренностями сети самостоятельно, то мог пропустить какие-то важные моменты. Может кто увидит какие-то недостатки приведённого ниже алгоритма и подскажет как увеличить скорость работы устройства. Итак, в устройство периодически по сети передаются данные блоком размером приблизительно в 16-20 кБ. Эти данные записываются в масив памяти и по таймеру процесора обрабатываются. Когда я програмировал работу с сетью то передачу данных сделал блоками по 1500 Байт. Может я что-то не учёл, а может тогда вылезали другие ошибки, но при передачи блока большей длины у меня подвисал процесор (приёмный буфер установлен приблизительно на 2кБ), поэтому сделать так как в USB, когда я пишу в порт всё одним куском, на уровне USB контролера масив разбивается на части, а в процесоре я уже собираю данные (гарантированно доставленные), мне не удалось. Сейчас я смотрю, что похоже можно в обработчике прерываний от сети поставить свой код анализа входных данных и сделать похоже как в USB но не уверен - не буду ли я получать повреждённые даные, которые долго нужно будет перефрагментировать, проверять и т.д. Сейчас у меня скорость передачи данных приблизительно 2Мб/с по 100 мегабитной сети. Выглядит это приблизительно так (результат теперешнего анализа с помощью Ethereal): отсылается пакет размером в 1500 байт в процесор, приблизительно через 4мс (время работы стека и моего копирования порции в нужное место памяти) процесор отсылает однобайтный пакет-подтверждения о приёме данных (чтобы внешняя программа не начала посылать данные пока я не обработал предыдущую порцию - правильно ли?), приблизительно через (дома забыл логи поэтому тут цыфру не помню) толи 1, толи 0,1мс, отсылается следующая порция данных. В результате 16кБ передаётся приблизительно за 50мс. Долго, было бы хорошо хотя бы в 2 раза быстрее. Можно ли улучшить скорость? Я смотрел, что при обработке стек копирует данные из буфера контролера в память, а потом я копирую куда мне нужно. Может можно сразу копировать без промежуточного буфера, но не будут ли проблемы с проверкой ошибок при передаче? Может в стеке uIP можно убрать лишнюю обработку?
Пока что я в процессе анализа кода, может ещё что и сам найду, но за любые советы и предложения буду искренне благодарен.
|
|
|
|
|
 |
Ответов
|
Apr 22 2008, 11:06
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 5-12-06
Пользователь №: 23 146

|
Цитата(prottoss @ Apr 22 2008, 12:04)  Закончил примерно с месяц встраиваемый HTTP-сервер + SNMP-агент на AT91SAM7X256. Стек использовал свой - давным-давно переделанный OpenTCP. Самый большой тормоз, ИМХО, в таких приложениях - использование memcpy, хотя МК распологает возможностью не использовать данную функцию. Код выложить не могу, ибо мое. Идея относительно простая:
1. Пишем свой менеджер памяти для работы с блоками по 128 байт (размерность для принимаемых блоков EMAC SAM7X).
2. Выделяем драйверу EMAC и стеку TCP/IP блоки.
3. При получении данных драйвер отдает список блоков с принятым пакетом а стек драйверу взамен свободные блоки. При этом производится обмен только указателями. Как такового не нужного копирования данных не происходит.
4. Соответсвенно, приложения(задачи) верхнего уровня (могут быть) тоже заточены под такой обмен данными.
При отправке данных опять происходит обмен указателями между драйвером и стеком(приложением).
Скорость, честно говоря не мерял, но работает довольно шустро - сетка прнимерно из 3-х сотен машин Очень хороша идея. Главное, что сам похожие вещи делал, при чём в этом же проекте, а тут использовать не догадался. Попробую
|
|
|
|
|
Apr 22 2008, 13:08
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата в таких приложениях - использование memcpy Да от memcpy надо уходить. Но даже с копированием, если сразу по 4 байта, и без проверок на выход за границы скорость значительно возрастет. e.g.: Код static void memcpy_burst( U32 *pDest, U32 *pSrc, U32 size ) { U32 wCnt = (size + 3) >> 2; // words count to be copied do { *pDest++ = *pSrc++; } while (--wCnt); } данные обязательно должны быть 32bit-aligned.
|
|
|
|
|
May 4 2008, 10:45
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(aaarrr @ May 4 2008, 12:06)  Не надо уходить от memcpy! Обойти можно только наложив дополнительные ограничения, например ввиде обязательной выровненности даннных.... А так сложно.. memcpy() не вовсех либах хороши  у 4 IAR - отвратительные, а в 5 резко улучшили, даже отдельно хвастались, что дескать самый быстрый стал.. При испытаниях действительно в некоторых условиях превосходил ранее мной используемый для старых IAR: CODE NAME memcpy
RSEG CSTACK:DATA:NOROOT(2)
MULTWEAK ??memcpy??rT MULTWEAK ??memmove??rT PUBLIC memcpy PUBLIC memmove
memcpy SYMBOL "memcpy" ??memcpy??rT SYMBOL "??rT", memcpy
memmove SYMBOL "memmove" ??memmove??rT SYMBOL "??rT", memmove
RSEG CODE:CODE:NOROOT(2) THUMB ??memcpy??rT: BX PC Nop REQUIRE memcpy
RSEG CODE:CODE:NOROOT(2) ARM
#ifndef configUSE_MEMCPY8W #define WORDS8_TRANSFER 0 #else #if configUSE_MEMCPY8W == 1 #define WORDS8_TRANSFER 1 #else #define WORDS8_TRANSFER 0 #endif #endif
//--------------------------------------------------------------------------- // void *(memcpy)(void *p1, const void *p2, size_t n) // Copy char p2[n] to p1[n] //--------------------------------------------------------------------------- memcpy: teq r2,#0 // Is p1 == 0 ? bxeq lr // If p1 == 0, return
stmdb sp!,{lr} // Push return address mov r12,r0 // Copy pointer p1 cmp r2,#8 // Is buffer long or short? ble byteserial // Jump if n <= 8
sub r3,r0,r1 // Compare pointers p1, p2 tst r3,#3 // Strings aligned same? bne byteserial // Jump if buffers not aligned
// Both strings are similarly aligned WRT word boundaries. // At least a portion of the data can be copied an entire // word at a time, which is faster than copying bytes. wordserial: ands r3,r0,#3 // Check byte alignment beq wordaligned // Jump if p1, p2 word-aligned
rsb r3,r3,#4 // m = no. of odd initial bytes sub r2,r2,r3 // n = n - m
// If the two buffers do not begin on word boundaries, begin // by copying the odd bytes that precede the first full word. preloop: ldrb lr,[r1],#1 // Read byte from source subs r3,r3,#1 // --m (decrement loop count) strb lr,[r12],#1 // Write byte to destination bne preloop // Loop if more bytes to move
wordaligned: #if WORDS8_TRANSFER == 1 movs r3,r2,asr #5 // Any chunks of 8 words? beq octsdone // Jump if no 8-word chunks
and r2,r2,#0x1F // Subtract chunks from n stmdb sp!,{r4-r10} // Save registers on stack
// The strings are long enough that we can transfer at least // some portion of the data in 8-word chunks. octloop: ldmia r1!,{r4-r10,lr} // Load 8 words from source subs r3,r3,#1 // More 8-word chunks to move? stmia r12!,{r4-r10,lr} // Write 8 words to destination bne octloop // Loop if more chunks
ldmia sp!,{r4-r10} // Restore registers from stack
octsdone: #endif movs r3,r2,asr #2 // Any more whole words to move? beq wordsdone // Jump if no more whole words
// Copy as much of the remaining data as possible one word at // a time. wordloop2: ldr lr,[r1],#4 // Read next word from source subs r3,r3,#1 // Decrement word count str lr,[r12],#4 // Write next word to destination bne wordloop2 // Loop while more words to move
wordsdone: ands r2,r2,#3 // Any last bytes to transfer? beq theend // Return if already done
// The two strings do not end on word boundaries. // Copy the remaining data one byte at a time. byteserial: ldrb lr,[r1],#1 // Read byte from source subs r2,r2,#1 // --n (decrement loop count) strb lr,[r12],#1 // Write byte to destination bne byteserial // Loop if more bytes to move
theend: ldmia sp!,{lr} // Return bx lr
//--------------------------------------------------------------------------- RSEG CODE:CODE:NOROOT(2) THUMB ??memmove??rT: BX PC Nop REQUIRE memmove
RSEG CODE:CODE:NOROOT(2) ARM
//--------------------------------------------------------------------------- // Safely copy c bytes from source s to destination d. // void *memmove(void *d, const void *s, unsigned c); //--------------------------------------------------------------------------- memmove: cmp r0,r1 // Is d > s ? bls memcpy // Jump to memcpy if d <= s
// Need to copy backwards, starting at tail ends of source and // destination arrays. Copy a word or a byte at a time? orr r3,r1,r0 // tmp = s | d orr r3,r3,r2 // tmp = s | d | c ands r3,r3,#3 // Is tmp even multiple of 4?
add r1,r1,r2 // s + c (end of source buffer) add r2,r2,r0 // d + c (end of dest'n buffer) beq move1 // Jump if tmp is multiple of 4 b move2
// Because the source and destination arrays are not aligned to even // word boundaries in memory, transfer only a byte at a time. move3: ldrb r3,[r1,#-1]! // Load next byte from source strb r3,[r2,#-1]! // Store next byte to dest'n move2: teq r0,r2 // More bytes to move? bne move3 // Jump if more bytes bx lr // All done
// Because count c is an even multiple of 4 and the source // and destination arrays begin on even word boundaries, move // an entire word at a time from source to destination. move4: ldr r3,[r1,#-4]! // Load next word from source str r3,[r2,#-4]! // Store next word to dest'n move1: teq r0,r2 // More words to move? bne move4 // Jump if more words
bx lr // All done
END
А 'уходить' по любому надо, но максимально исключая пересылки память-память в пинципе  Цитата(defunct @ May 3 2008, 23:26)  Но для SAM7 это не так. Надо помнить что слабое место у SAM7 это флеш. В ARM режиме размер кода увеличивается в среднем на 30%, а это значит как минимум на 30% больше обращений к медленной флеш. Плюс в SAM7 применена технология ускоренной выборки для Thumb режима (по две Thumb инструкции за одно обращение к флеш). Т.е. при размещении программы во флеш Thumb режим заведомо в выигрыше. 1. К счатью на SAM7 свет клином не сошелся  . 2. Все не так радужно и с Thumb - на моих реальных программах много использующих 32-битовость увеличение размера кода МНОГО меньше, а количество команд которые по любому надо исполнять ЗАМЕТНО больше. Практически вышесказанное Вами в большей степени относится к коду написанному в "восьмибитном" стиле с обильным использованием 8-бит переменных, что изрядно душит ARM (в обоих режимах). Для изначально "правильных" программ Thumb у меня ПРОИГРАЛ. Правда на SAM7 не гонял, а на LPC там, конечно, MAM описанный Вами эффект дополнительно сглаживает, но не слишком, ибо частота повыше а Flash потормознее.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
Сообщений в этой теме
OlegHmt Как повысить скорость работы по сети AT91SAM7X256 Apr 22 2008, 07:21 _dem 2 мегабита или 2 мегабайта ? Apr 22 2008, 07:26 OlegHmt Цитата(_dem @ Apr 22 2008, 10:26) 2 мегаб... Apr 22 2008, 08:03 Gemm Цитата(OlegHmt @ Apr 22 2008, 11:21) ...
... Apr 22 2008, 08:01 chds А транспорт UDP или TCP?
Мы юзали uCOS у нас с под... Apr 22 2008, 08:24 OlegHmt Цитата(chds @ Apr 22 2008, 11:24) А транс... Apr 22 2008, 08:36    prottoss Цитата(aaarrr @ May 4 2008, 17:06) Не над... May 4 2008, 13:01     zltigo Цитата(prottoss @ May 4 2008, 15:01) Free... May 4 2008, 16:33      prottoss Цитата(zltigo @ May 4 2008, 23:33) Мне с... May 4 2008, 16:58      defunct Цитата(zltigo @ May 4 2008, 19:33) По быс... May 4 2008, 20:09 _dem Какую скорость требуется получить ?
на uip много ... Apr 22 2008, 14:33 OlegHmt Цитата(_dem @ Apr 22 2008, 17:33) Какую с... Apr 22 2008, 14:59 OlegHmt Писать свой менеджер памяти, пока для меня будет с... May 3 2008, 20:30 defunct Цитата(OlegHmt @ May 3 2008, 23:30) А пок... May 3 2008, 21:26  Rst7 Цитата(defunct @ May 4 2008, 00:26) В ARM... May 4 2008, 11:06   defunct Цитата(Rst7 @ May 4 2008, 14:06) Вы уж пр... May 4 2008, 13:58    prottoss Цитата(defunct @ May 4 2008, 20:58) Есть ... May 4 2008, 14:17     defunct Цитата(prottoss @ May 4 2008, 17:17) Я же... May 4 2008, 14:26      prottoss Цитата(defunct @ May 4 2008, 21:26) Ну ка... May 4 2008, 14:55       defunct Цитата(prottoss @ May 4 2008, 17:55) hIP ... May 4 2008, 14:59        prottoss Цитата(defunct @ May 4 2008, 21:59) Ок, к... May 4 2008, 15:17         defunct Цитата(prottoss @ May 4 2008, 18:17) Но о... May 4 2008, 15:20          prottoss Цитата(defunct @ May 4 2008, 22:20) Под m... May 4 2008, 15:27           defunct Цитата(prottoss @ May 4 2008, 18:27) Я го... May 4 2008, 15:33            prottoss Цитата(defunct @ May 4 2008, 22:33) Ну ды... May 4 2008, 15:52            prottoss Цитата(defunct @ May 4 2008, 22:33) Указа... May 4 2008, 16:01             defunct prottoss
можете привести реальные цифры?
Сколько у... May 4 2008, 16:10              prottoss Цитата(defunct @ May 4 2008, 23:10) prott... May 4 2008, 16:48          blackfin Цитата(defunct @ May 4 2008, 19:20) Может... May 4 2008, 15:53           defunct Цитата(blackfin @ May 4 2008, 18:53) Это ... May 4 2008, 15:58            blackfin Цитата(defunct @ May 4 2008, 19:58) А с ч... May 4 2008, 16:37             zltigo Цитата(blackfin @ May 4 2008, 18:37) Если... May 4 2008, 16:52              blackfin Цитата(zltigo @ May 4 2008, 20:52) Ага, т... May 4 2008, 16:59               zltigo Цитата(blackfin @ May 4 2008, 18:59) Став... May 4 2008, 17:47                blackfin Цитата(zltigo @ May 4 2008, 21:47) Будет ... May 4 2008, 17:58                 zltigo Цитата(blackfin @ May 4 2008, 19:58) Меня... May 4 2008, 18:09    aaarrr Цитата(defunct @ May 4 2008, 17:58) Надо ... May 4 2008, 15:15 OlegHmt Понятно, тогда вопрос со стороны lwIP - можно ли и... May 3 2008, 22:30 defunct Цитата(OlegHmt @ May 4 2008, 01:30) Перво... May 3 2008, 23:12  OlegHmt Цитата(defunct @ May 4 2008, 02:12) А чем... May 4 2008, 07:36 Rst7 Цитатарасчитаной на быстрое копирование выровненны... May 4 2008, 15:19 Rst7 ЦитатаНу дык на 60-ти байтных пакетах +/- попугай ... May 4 2008, 15:43 Rst7 ЦитатаДлина блоков, применительно к SAM7X уже выбр... May 4 2008, 16:37 AlexandrY Возьмите процы от Freescale, в них IP-core Ethern... May 4 2008, 21:32 zltigo Цитата(AlexandrY @ May 4 2008, 23:32) RTO... May 5 2008, 08:07  AlexandrY Я ж не предлагаю отказаться от оси. Это ж святое... May 5 2008, 09:19 OlegHmt Ну и темку же я поднял
Поделюсь результатами кот... May 5 2008, 06:59 Rst7 ЦитатаВозьмите процы от Freescale, в них IP-core ... May 5 2008, 09:44 AlexandrY Не забывают, а не договаривают. Ну не всеж сразу в... May 5 2008, 10:24 Rst7 ЦитатаЕсть такой тэг VLAN, в MAC хидере. Используя... May 5 2008, 11:12 AlexandrY Вообще-то я просто прикалывался, но была одна мелк... May 5 2008, 13:20
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|