2014-12-18 2 views
1

Мы разрабатываем пользовательскую плату на базе Cyclone V. Это FPGA + ARM Soc работает с встроенным ядром Linux 3.10-ltsi. Наше предназначение - отправить через кучу необработанных огромных данных в памяти в пределах 50-400 МБ для Java-клиента, работающего под управлением Windows 7, через TCP-гигабитный ethernet. iperf показывает, что пропускная способность TCP нашей платы составляет 6xxMBit/s. Вопросы: 1. У нас есть требование, когда нам необходимо отправить данные необработанной памяти в течение определенного интервала. Итак, каков правильный способ измерения пропускной способности для нашего случая? В настоящее время мы просто оборачивать отправки кода с gettimeofday так:Измерьте и улучшите пропускную способность гигабитного Ethernet

int total_sent = 0, bytes_sent = 0; 
gettimeofday(&t0, 0); 
for (total_sent = 0; total_sent < data_size;) { 
    bytes_sent = write(conn_fd, buf + total_sent, data_size - total_sent); 
    if (bytes_sent == -1) 
     break; 
    total_sent += bytes_sent; 
} 
gettimeofday(&t1, 0); 

unsigned long elapsed_us = (t1.tv_sec - t0.tv_sec) * 1000000 + t1.tv_usec - t0.tv_usec; 
double elapsed_s = (double)elapsed_us/1000000; 
printf("Throughput: %f Mbit/s\n", img_size * 8/elapsed_s/1000000); 
printf("Total bytes sent: %d\n", total_sent); 

Является ли это правильный метод для измерения пропускной способности?

2. Возможно ли увеличить пропускную способность через два Ethernet-порта? Что-то вроде нарезания необработанных данных на две части и отправки их по двум портам.

3.Что лучший способ увеличить пропускную способность в нашем случае? Максимальная пропускная способность, которую мы хотели бы достичь, составляет 1024 Мбит/с.

+2

На этот раз, вы просто не можете достичь 1Gbps, поскольку протоколы (Ethernet, IP, TCP) имеют накладные расходы. Вы должны быть очень близки, но если вам действительно нужна высокая пропускная способность, вы можете захотеть перейти на UDP вместо TCP, но тогда вам придется реализовать легкий TCP-подобный протокол самостоятельно для обработки переупорядочения пакетов/потерь. Также обратите внимание, что 1 Гбит/с не 1024 Мбит/с, это 1000 Мбит/с. –

+0

Я понимаю, что 1 Гбит/с составляет 1000 Мбит/с. 1024 Мбит/с, о котором я упоминал, является наихудшим случаем для ограничения пропускной способности. Используя UDP, можно ли достичь пропускной способности более 1 Гбит/с? – czteoh

ответ

0
  1. Несколько комментариев: накладные расходы на системный вызов gettimeofday() перечеркивают ваши измерения.

  2. Убедитесь, что драйвер порта Ethernet включен NAPI.

  3. Если вы хотите максимальную пропускную способность, попробуйте получить нулевую копию. Если вы застряли в TCP, возможно, вы можете сделать что-то, используя vmsplice() (см.: vmsplice() and TCP).

  4. Для достижения наилучших результатов, дамп TCP, используйте пакетный сокет с опцией PACKET_MMAP (http://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/) и осуществлять надежный UDP протокола (например, https://bitsecant.googlecode.com/svn-history/r8/trunk/src/net/rudp/ReliableServerSocket.java для реализации JAVA для Win 7 сверстников).

Успехов

+0

Я рассмотрю ваши предложения. Что касается нулевой копии AFAIK, нам нужен файловый дескриптор, чтобы правильно использовать sendfile() и splice()? Потому что в моем случае данные уже находятся внутри памяти. Кстати, какой правильный/точный метод измерения пропускной способности для моего случая? – czteoh

+0

vmsplice() - это «сращивание из виртуальной памяти» - именно то, что вам нужно. Что касается измерений, если данные, которые вы отправляете, достаточно велики, накладные расходы gettimeofday(), вероятно, в любом случае незначительны в вашем случае, но в других случаях я бы использовал счетчик циклов вашей платформы - то, что не требует системы вызов и переключатель контекста ядра. Опять же, в этом конкретном случае, если просмотр отправки запущен для многих итераций, это, вероятно, не имеет значения – gby

Смежные вопросы