Медленная передача Ethernet из памяти Cyclone V FPGA DDR3 - PullRequest
0 голосов
/ 20 мая 2019

Мы используем CycloneV в нашем проекте, FPGA будет записывать данные в DDR, используя шину AXI, и наше приложение должно отправлять данные через Ethernet. Мы измеряем нашу пропускную способность Ethernet с помощью iperf, и она может достигать скорости около 700 Мбит / с. Когда мы тестируем производительность нашего приложения, мы получаем только 300 Мбит / с. Нам нужно знать, почему наша передача медленная по сравнению с тестом iperf.

Память DDR3 зарезервирована во время загрузки для прямого доступа к ПЛИС

Можете ли вы посоветовать, почему моя передача по Ethernet медленнее, чем данные, измеренные iperf (~ 700 Мбит / с), и как я могу увеличить свою пропускную способность?

if ((fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1)
{
    printf("ERROR: could not open /dev/mem/ \n");
}

pMem = mmap(NULL, SDRAM_64_SPAN, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, SDRAM_64_BASE);

if (pMem == MAP_FAILED)
{
    printf("ERROR: mmap failed\n");
}

Клиентский сокет, работающий в SoC, который отправляет около 1 Мбайт данных, а сервер находится на ПК, который непрерывно принимает данные

Код клиента, который вызывается только один раз

sock = socket(AF_INET, SOCK_STREAM, 0);
int n = 1024*2*1024;
unsigned int m = sizeof(n);
if ((setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &n, m) < 0)
{
    printf("ERROR: Setting socket send buffer size\n");
}

int opt = 1;
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) > 0)
{
    printf("ERROR: Unable to set TCP no delay\n");
}

if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
    printf("ERROR: connecting to server\n");
}

int flags = fcntl(sock, F_GETFL, 0);
int newflags = flags | (int) O_NONBLOCK;
if (fcntl(sock, F_SETFL, newflags) < 0)
{
    printf("ERROR: setting non blocking mode\n");
}

При каждой передаче данных клиент продолжает отправлять данные следующим образом

int len = 128*256*4*8;
int r = sendall(sock, (char *)pMem, &len);

if (r == -1)
{
    printf("ERROR: sending data\n");
}

int sendall(int s, char *buf, int *len)
{
    int total = 0;
    int bytesleft = *len;
    int n;

    while (total < *len)
    {
        n = 0;
        n = send(s, buf + total, bytesleft, 0);
        if ((n == -1) && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
        {
            n = 0;
            usleep(5);
        }
        else
        {
            if (n < 0)
            {
                printf("ERROR: sending data\n");
                break;
            }
        }

        total += n;
        bytesleft -= n;
    }

    *len = total;

    return n==-1?-1:0;
}

...