但し、基本的に通信性能向上とメモリ使用量はトレードオフとなる為、
最終的なコンフィグレーション設定値は、アプリケーションの設計に適した値を検討した上でカスタマイズしてください。
注意:評価版ではコンフィグレーション制限がある為、この手順を実施する事は出来ません。
1.通信速度を計測するテストプログラムヘッダ(sample_throughput.h)を作成
コード: 全て選択
#ifndef SAMPLE_THROUGHPUT_H_
#define SAMPLE_THROUGHPUT_H_
extern UW total_byte;
extern UW pps;
typedef ER (*FP_SNDRCV)(SID sid, VP data, UH len);
typedef struct t_task_param
{
    UB proto;          // 生成するソケットのプロトコル(IP_PROTO_TCP or IP_PROTO_UDP)
    UH data_size;      // 送受信サイズ(1-32768)
    UB con_flg;        // 接続モード(0 or SOC_SER or SOC_CLI)
    FP_SNDRCV api;     // 使用する関数ポインタ(&snd_soc or &rcv_soc)
} T_TASK_PARAM, *PT_TASK_PARAM;
void ThroughputTask(VP_INT exinf);
#endif
コード: 全て選択
#include "kernel.h"
#include "net_hdr.h"
#include "net_strlib.h"
#include "sample_throughput.h"
static char buf[32768];
UW total_byte = 0UL;
UW pps = 0UL;
void ThroughputTask(VP_INT exinf)
{
    PT_TASK_PARAM pParam;
    SID sid;
    T_NODE host;
    T_NODE remote;
    ER ercd;
    sid = 0U;
    pParam = (PT_TASK_PARAM)exinf;
    /* ソケット生成 */
    host.num  = 1;
    host.ver  = IP_VER4;
    host.ipa  = INADDR_ANY;
    host.port = 12345;
    ercd = cre_soc( pParam->proto, &host );
    if ( ercd <= 0 ) {
    	goto TASK_END;
    }
    sid = (SID)ercd;
    /* TCPクライアント接続 */
    remote.ver = IP_VER4;
    remote.num = 1;     /* ネットワークデバイス番号 */
    remote.ipa = ip_aton( "172.16.0.1" );
    remote.port = 10000;
    ercd = con_soc( sid, &remote, pParam->con_flg );
    if ( ercd != E_OK ) {
    	goto TASK_END;
    }
    /* スループット計測 */
    for ( ; ; ) {
        ercd = (pParam->api)( sid, &buf[0], pParam->data_size );
        if ( ercd <= 0 ) {
        	break;
        }
        total_byte += (UW)ercd;
        pps++;
    }
TASK_END:
    /* 後始末 */
    if ( sid != 0U ) {
        cls_soc( sid, 0 );
        del_soc( sid );
        sid = 0U;
    }
    ext_tsk();
}
※このトピックの例では、HELIO.NETサンプルプログラムのmain.c内にあるMainTaskをベースに実装しました コピーペースト用テンプレート
コード: 全て選択
#define TCP_THROUGHPUT_ENABLE
T_CTSK ctsk_throughput = { TA_HLNG | TA_ACT | TA_FPU, (VP_INT)0, (FP)ThroughputTask, 5, 0x400, 0, "ThroughputTask" };
void MainTask(VP_INT exinf)
{
    T_TASK_PARAM param = { 0 };
    VB msg[32];
    ER ercd;
    ini_com(ID_UART, &uart_ini);
    ctr_com(ID_UART, STA_COM, 0);
    ctr_com(ID_UART, SND_BRK, 100);
    puts_com_opt((VB *)demo_str);
    /* Initialize Network */
    ercd = net_setup();
    if (ercd != E_OK) {
        return;
    }
    /* スループット計測タスク生成 */
#ifdef TCP_THROUGHPUT_ENABLE
#if 1
    param.proto = IP_PROTO_TCP;
    param.data_size = 32768;
    param.con_flg = SOC_CLI;
    param.api = &snd_soc;
#else
    param.proto = IP_PROTO_TCP;
    param.data_size = 32768;
    param.con_flg = SOC_SER;
    param.api = &rcv_soc;
#endif
#else
#if 1
    param.proto = IP_PROTO_UDP;
    param.data_size = 1472;
    param.con_flg = 0;
    param.api = &snd_soc;
#else
    param.proto = IP_PROTO_UDP;
    param.data_size = 1472;
    param.con_flg = 0;
    param.api = &rcv_soc;
#endif
#endif
    ctsk_throughput.exinf = (VP_INT)¶m;
    acre_tsk( (T_CTSK *)&ctsk_throughput );
    for ( ; ; ) {
        tslp_tsk( 1000 );
        sprintf( &msg[0], "%dMbps, pps = %d\r\n", (total_byte * 8) / 1000 / 1000, pps );
        puts_com_opt( &msg[0] );
        total_byte = 0UL;
        pps = 0UL;
    }
#if 0
    /* Start UART console */
    net_sta_console();
#endif
    return;
}
■TCP送信性能
計測コマンド:「iperf -s -p 10000 -i 10」 ■TCP受信性能
以下を変更してリビルドし実行 計測コマンド:「iperf -c 172.16.0.95 -p 12345 -i 10 -w 64000 -t 200」 ■UDP送信性能
以下を変更してリビルドし実行 計測コマンド:「iperf -s -u -p 10000 -i 10 -l 1472」 ■UDP受信性能
以下を変更してリビルドし実行 計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 1472 -i 10 -b 810M -t 200」 ■デフォルト設定のスループット性能
TCP送信性能:55Kbps
TCP受信性能:90Mbps
UDP送信性能:495Mbps
UDP受信性能:500Mbps
5.次に通信性能に関わるコンフィグレーションのカスタマイズを行います。
■net_cfg.h ■DDR_CYCLONEV_ETH_cfg.h(ドライバによって名称が異なります) CFG_TCP_SND_WNDの値をデフォルト1024から16384に変更(TCPの送信性能に影響します)
CFG_TCP_RCV_WNDの値をデフォルト1024から32768に変更(TCPの受信性能に影響します)
CFG_PKT_RCV_QUEの値をデフォルト1から255に変更(UDPの受信性能に影響します。また、UDPパケット取りこぼしにも影響します)
ETH1_RXDESC_CNTの値をデフォルト4から18に変更(Ethernetドライバのパケット受信性能に影響します)
■TCP送信性能
計測コマンド:「iperf -s -p 10000 -i 10」 ■TCP受信性能
計測コマンド:「iperf -c 172.16.0.95 -p 12345 -i 10 -w 64000 -t 200」 ■UDP送信性能
計測コマンド:「iperf -s -u -p 10000 -i 10 -l 1472」 ■UDP受信性能
計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 1472 -i 10 -b 810M -t 200」 1472バイトを超えるUDPパケットの送受信が失敗してしまう
上記トピックにてIPフラグメントの受信を行える形にした上で受信処理を行うとUDP受信性能の向上が確認出来ます。
送信処理はIPフラグメントを行わない方が性能が出るみたいです。
トピック対応を行い、UDP送受信バイト数の設定を変更 トピック対応を行い、スループット計測を行う処理を一部変更 ■UDP送信性能(IPフラグメント)
計測コマンド:「iperf -s -u -p 10000 -i 10 -l 5888」 ■UDP受信性能(IPフラグメント)
計測コマンド:「iperf -u -c 172.16.0.95 -p 12345 -l 5888 -i 10 -b 960M -t 200」 ■カスタマイズ設定後のスループット性能
TCP送信性能:434Mbps
TCP受信性能:948Mbps
UDP送信性能:518Mbps(IPフラグメント無しの場合) → 376Mbps(IPフラグメント有りの場合)
UDP受信性能:813Mbps(IPフラグメント無しの場合) → 960Mbps(IPフラグメント有りの場合)
■コンフィグレーション内容まとめ(※1)
Ethernetドライバの送受信タスクの優先度 = 4(※2)
スループット計測タスク(ThroughputTask)の優先度 = 5(※2)
TCP送信バッファサイズ(CFG_TCP_SND_WND) = 16384
TCP受信ウィンドウサイズ(CFG_TCP_RCV_WND) = 32768
UDP受信キュー数(CFG_PKT_RCV_QUE) = 255
Ethernetドライバ送信ディスクリプタ数 = 4
Ethernetドライバ受信ディスクリプタ数 = 18
※1:色々試した結果、上記の設定で一番性能を出す事が出来ました。
ただ、環境によって適切な値があると思うので参考値としてください。
※2:性能的にはEthernetドライバ > アプリケーションタスクの優先度の方が良い結果が出ます
■その他・補足
本サンプルはuC3/Standardをベースでのサンプルとなっています。
uC3/Compactで同様の事をやる場合は以下の点に注意してカスタマイズしてください。
1.CompactではコンフィグレータでTCPソケットの送信バッファや受信ウィンドウサイズをカスタマイズする機能があります。
従って、送信バッファや受信ウィンドウサイズを変更する場合はコンフィグレータから変更してください。
※ソケット生成の仕組みがStandardとは異なる為、net_cfg.hのCFG_TCP_SND_WNDやCFG_TCP_RCV_WNDの値を直接変更したとしても設定値として反映されないので注意が必要です。
2.CompactとStandardでは、del_soc()などいくつかサポートされていないAPIが存在します。
従って、Compactに本サンプルを適用する場合はサポートされていないAPIの処理は削除してください。