main.c

    1|/************************************************************************
    2|*  <<< コンパイラが吐くV800命令の確認 >>>
    3|*************************************************************************/
    4|
    5|#define a_size  655360
    6|#define b_size  2621440
    7|
    8|int a[a_size];
    9|char b[b_size];
   10|typedef struct { int a; int b; }  STRUCT;
   11|typedef struct { int a; int b; int c; int d; }  STRUCT2;
   12|typedef struct { int a; int b; int c; int d; int e; int f; }  STRUCT3;
   13|
   14|void  bp(){}
   15|void  bench1();
   16|void  bench2();
   17|void  bench3();
   18|void  bench4();
   19|void  bench5();
   20|void  benchX();
   21|
   22|void  main()
   23|{
   24|/*bench1();*/
   25|/*bench2();*/
   26|/*bench3();*/
   27|  bench4();
   28|/*bench5();*/
   29|}
   30|
   31|
   32|/************************************************************************
   33|*  <<< int* と char* の比較 [bench1()]>>>
   34|*************************************************************************/
   35|void  bench1()
   36|{
   37|  int  i;
   38|bp();
   39|  for ( i = 0; i < a_size; i++ )
   40|    a[i] = 0;     /* ST.W : 0.0160756(sec) */
   41|bp();
   42|  for ( i = 0; i < b_size; i++ )
   43|    b[i] = 0;     /* ST.B : 0.0643025(sec), ループ処理に時間が掛かる */
   44|bp();
   45|  for ( i = 0; i < a_size; i++ )
   46|    b[i] = 0;     /* ST.B : 0.0160757(sec), ST.W と同じ時間 */
   47|bp();
   48|}
   49|
   50|
   51|/************************************************************************
   52|*  <<< 配列とポインタの比較 [bench2()]>>>
   53|*【内容】
   54|*・アクセスするときの文法、a[0] と *a の違い
   55|*・アクセスする対象が配列直接かポインタ経由かによる違い
   56|*・この比較は、ループの外のケースである
   57|*【結果】
   58|*・処理時間に関しては、どれがいいとは判断できない。
   59|*・機械語長に関して、
   60|*  ・グローバルな配列をポインタに格納するのは×
   61|*  ・配列を引数で渡した方が◎
   62|*・スタック量に関しては、どれがいいとは判断できない。
   63|*【結論】
   64|*・配列は引数で渡す。
   65|*・ループの外では、文法は a[0] でも *a でも処理時間は変わらない。
   66|*
   67|*【データ】
   68|*(コンパイラ=GHS, 最適化=なし)
   69|*  ケース | スタック量  機械語長F 処理時間
   70|*  --------------------------------------------------------------
   71|*   a  |   4       26      2.452945 ******
   72|*   b  |   4       26      2.452945 ******
   73|*   c  |   4       22      2.452945 ******
   74|*   d  |   4       22      2.525207 *********
   75|*   e  |   4       30      2.452945 ******
   76|*   f  |   4       30      2.452944 *****
   77|*   g  |   4       24      2.452945 ******
   78|*   h  |   4       24      2.525208 **********
   79|*   i  |   4       22      2.452945 ******
   80|*   j  |   4       22      2.525207 *********
   81|*(コンパイラ=GHS, 最適化=あり)
   82|*  ケース | スタック量  機械語長F 処理時間
   83|*  --------------------------------------------------------------
   84|*   a  |   4       26      2.452946 ******
   85|*   b  |   4       26      2.525207 ********
   86|*   c  |   4       22      2.525208 *******
   87|*   d  |   4       22      2.525208 *******
   88|*   e  |   4       30      2.525208 *******
   89|*   f  |   4       30      2.626216 **********
   90|*   g  |   4       22      2.525208 *******
   91|*   h  |   4       22      2.525208 *******
   92|*   i  |   4       22      2.525208 *******
   93|*   j  |   4       22      2.525208 *******
   94|*(機械語長F は、関数全体のバイト数、機械語長L は、ループ内のバイト数)
   95|*************************************************************************/
   96|  void  bench2a();  void  bench2b();
   97|  void  bench2c( int a[] );  void  bench2d( int a[] );
   98|  void  bench2e();  void  bench2f();
   99|  void  bench2g( int a[] );  void  bench2h( int a[] );
  100|  void  bench2i( int* p );  void  bench2j( int* p );
  101|  void  bench2x( int n );
  102|
  103|void  bench2()
  104|{
  105|  int   i;
  106|  int   loop = 10000000;
  107|
  108|bp();
  109|  for ( i = 0; i < loop; i++ )
  110|    bench2a();
  111|bp();
  112|  for ( i = 0; i < loop; i++ )
  113|    bench2b();
  114|bp();
  115|  for ( i = 0; i < loop; i++ )
  116|    bench2c( a );
  117|bp();
  118|  for ( i = 0; i < loop; i++ )
  119|    bench2d( a );
  120|bp();
  121|  for ( i = 0; i < loop; i++ )
  122|    bench2e();
  123|bp();
  124|  for ( i = 0; i < loop; i++ )
  125|    bench2f();
  126|bp();
  127|  for ( i = 0; i < loop; i++ )
  128|    bench2g( a );
  129|bp();
  130|  for ( i = 0; i < loop; i++ )
  131|    bench2h( a );
  132|bp();
  133|  for ( i = 0; i < loop; i++ )
  134|    bench2i( a );
  135|bp();
  136|  for ( i = 0; i < loop; i++ )
  137|    bench2j( a );
  138|bp();
  139|}
  140|
  141|void  bench2a()
  142|{
  143|  bench2x( *a );
  144|}
  145|
  146|void  bench2b()
  147|{
  148|  bench2x( a[0] );
  149|}
  150|
  151|void  bench2c( int a[] )
  152|{
  153|  bench2x( *a );
  154|}
  155|
  156|void  bench2d( int a[] )
  157|{
  158|  bench2x( a[0] );
  159|}
  160|
  161|void  bench2e()
  162|{
  163|  int*  p = a;
  164|
  165|  bench2x( *p );
  166|}
  167|
  168|void  bench2f()
  169|{
  170|  int*  p = a;
  171|
  172|  bench2x( p[0] );
  173|}
  174|
  175|void  bench2g( int a[] )
  176|{
  177|  int*  p = a;
  178|
  179|  bench2x( *p );
  180|}
  181|
  182|void  bench2h( int a[] )
  183|{
  184|  int*  p = a;
  185|
  186|  bench2x( p[0] );
  187|}
  188|
  189|void  bench2i( int* p )
  190|{
  191|  bench2x( *p );
  192|}
  193|
  194|void  bench2j( int* p )
  195|{
  196|  bench2x( p[0] );
  197|}
  198|
  199|void  bench2x( int n )
  200|{
  201|}
  202|
  203|
  204|/************************************************************************
  205|*  <<< ループ内の配列とポインタの比較 [bench3()]>>>
  206|*【内容】
  207|*・アクセスするときの文法、a[i] と *a; a++; の違い
  208|*・この比較は、ループの中のケースである
  209|*【結果】
  210|*・終点ポインタを使用(case-c)してもスタック量は増えない
  211|*・終点ポインタを使用(case-c)すると最も速い(19%〜31%高速)
  212|*・終点ポインタを使用(case-c)すると機械語長が最も短くなる
  213|*・最適化をかけると(case-c)では遅くなる
  214|*【結論】
  215|*・終点ポインタを使用(case-c)してループを回すとよい。
  216|*
  217|*【データ】
  218|*(コンパイラ=GHS, 最適化=なし)
  219|*  ケース | スタック量  機械語長F 機械語長L  処理時間
  220|*  ------------------------------------------------
  221|*   a  |  12        68        32      2.731492 ************
  222|*   b  |  12        62        26      2.350740 ********
  223|*   c  |  12        60        14      1.895615 *****
  224|*(コンパイラ=GHS, 最適化=あり)
  225|*  ケース | スタック量  機械語長F 機械語長L  処理時間
  226|*  ------------------------------------------------
  227|*   a  |  12        64        28      2.502401 **********
  228|*   b  |  12        62        26      2.424201 *********
  229|*   c  |  12        60        14      2.046562 ******
  230|*(機械語長F は、関数全体のバイト数、機械語長L は、ループ内のバイト数)
  231|*************************************************************************/
  232|  void  bench3a( int* a );  void  bench3b( int* a );  void  bench3c( int* a );
  233|  void  bench3x( int n );
  234|
  235|#define  bench3_loop   10000000
  236|
  237|void  bench3()
  238|{
  239|bp();
  240|  bench3a( a );
  241|bp();
  242|  bench3b( a );
  243|bp();
  244|  bench3c( a );
  245|bp();
  246|}
  247|
  248|void  bench3a( int* a )
  249|{
  250|  int  i;
  251|
  252|  for ( i = 0; i < bench3_loop; i++ )
  253|    bench3x( a[i] );
  254|}
  255|
  256|void  bench3b( int* a )
  257|{
  258|  int*  p;
  259|
  260|  for ( p = a; p < a + bench3_loop; p++ )
  261|    bench3x( *p );
  262|}
  263|
  264|void  bench3c( int* a )
  265|{
  266|  int*  p;
  267|  int*  p_e;
  268|
  269|  p_e = a + bench3_loop;
  270|  for ( p = a; p < p_e; p++ )
  271|    bench3x( *p );
  272|}
  273|
  274|void  bench3x( int n )
  275|{
  276|}
  277|
  278|
  279|/************************************************************************
  280|*  <<< 引数の渡し方の比較、ローカル変数キャッシュ使用の比較 [bench4()]>>>
  281|*【内容】
  282|*・引数で出力するか返り値で出力するかによる比較
  283|*・引数にメンバ変数を渡すか構造体を渡すかによる比較
  284|*・参照回数1回(ループ外)と参照回数 n回(ループ内)での比較
  285|*・アドレス渡し、構造体渡しの引数を、ローカル変数に置くかどうかによる比較
  286|*・構造体で一括指定する渡し方と基本型を並べる渡し方の比較
  287|*【結果】
  288|*・引数のアドレスを渡して格納するより、返り値で返す方が速い(33%高速)
  289|*・引数のアドレスを渡して格納するより、返り値で返す方が機械語長が小さい
  290|*  (100%小さい)
  291|*・メンバ変数渡しでも構造体渡しでも、機械語長、処理時間とも全く変わらない
  292|*  (メンバ変数に格納する値は返り値にするとよい)
  293|*・ループ内ならローカル変数を使用した方が速い(46%高速)
  294|*・ループ内に限った機械語長はローカル変数を使用した方が小さい(30%小さい)
  295|*・ローカル変数キャッシュを使用してもスタック量は増えない
  296|*・引数4つまでなら構造体で一括指定するよりも速い (12%〜20%高速)
  297|*・引数4つまでなら構造体で一括指定するよりも小さい (20%小さい)
  298|*・引数5つを超えると構造体で一括指定するよりも極端に遅くなる
  299|*・最適化をかけてもほとんど変わらない
  300|*【結論】
  301|*・基本型(メンバ変数)の出力は、返り値で返した方がよい
  302|*・構造体のうち複数のメンバ変数を変更するなら、構造体ごと渡す方がよい
  303|*・基本型でも構造体でもアドレス渡しならローカル変数にキャッシュする方がよい
  304|*・引数4つまでなら構造体で一括しない方がよい
  305|*
  306|*【データ】
  307|*(コンパイラ=GHS, 最適化=なし)
  308|*  ケース | スタック量  機械語長F 機械語長L  処理時間
  309|*  ------------------------------------------------
  310|*   a  |   4        18        --      4.905887 *************
  311|*   b  |   8        36        --      7.358829 ********************
  312|*   c  |   4        18        --      4.905887 *************
  313|*   d  |   8        36        --      7.358830 ********************
  314|*  ------------------------------------------------
  315|*   e  |   8        38        --      7.358830 ********************
  316|*   f  |   8        38        --      7.358830 ********************
  317|*   g  |  12        62        26      2.452946 *******
  318|*   h  |  12        64        20      1.313111 ****
  319|*   i  |   8        36        --      7.358830 ********************
  320|*   j  |   8        38        --      7.358830 ********************
  321|*   k  |  12        62        26      2.452947 *******
  322|*   l  |  12        64        20      1.313111 ****
  323|*  ------------------------------------------------
  324|*   m  |   0        22        12      1.717142 ******
  325|*   n  |   0        22         6      1.515125 ******
  326|*   o  |   0        22        24      2.222183 *********
  327|*   p  |   0        26        14      2.121174 *********
  328|*   q  |   0        22        30      2.626216 **********
  329|*   r  |   0        32        20      2.626215 **********
  330|*   s  |   0        22        36      2.929240 ***********
  331|*   t  |   0        38        26      4.905888 ******************
  332|*(コンパイラ=GHS, 最適化=あり)
  333|*  ケース | スタック量  機械語長F 機械語長L  処理時間
  334|*  ------------------------------------------------
  335|*   a  |   4        18        --      4.905887 *************
  336|*   b  |   8        36        --      7.358828 ********************
  337|*   c  |   4        18        --      4.905887 *************
  338|*   d  |   8        36        --      7.358829 ********************
  339|*  ------------------------------------------------
  340|*   e  |   8        36        --      7.358830 ********************
  341|*   f  |   8        36        --      7.358830 ********************
  342|*   g  |  12        62        26      2.452947 *******
  343|*   h  |  12        64        20      1.313111 ****
  344|*   i  |   8        36        --      7.358829 ********************
  345|*   j  |   8        36        --      7.358830 ********************
  346|*   k  |  12        62        26      2.452947 *******
  347|*   l  |  12        64        20      1.313119 ****
  348|*  ------------------------------------------------
  349|*   m  |   0        22        12      1.717142 ******
  350|*   n  |   0        22         6      1.515125 ******
  351|*   o  |   0        22        24      2.424199 *********
  352|*   p  |   0        26        10      1.919157 ********
  353|*   q  |   0        22        30      2.626216 **********
  354|*   r  |   0        32        14      2.452944 *********
  355|*   s  |   0        22        36      2.828232 ***********
  356|*   t  |   0        38        20      4.905888 ******************
  357|*(機械語長F は、関数全体のバイト数、機械語長L は、ループ内のバイト数)
  358|*************************************************************************/
  359|  int   bench4a( int a );  void  bench4b( int* a );
  360|  void  bench4e( int* a );  void  bench4f( int* a );
  361|  void  bench4g( int* a );  void  bench4h( int* a );
  362|  void  bench4i( STRUCT* s );  void  bench4j( STRUCT* s );
  363|  void  bench4k( STRUCT* s );  void  bench4l( STRUCT* s );
  364|  int   bench4m( STRUCT* s );
  365|  int   bench4n( int a, int b );
  366|  int   bench4o( STRUCT2* s );
  367|  int   bench4p( int a, int b, int c, int d );
  368|  int   bench4q( STRUCT3* s );
  369|  int   bench4r( int a, int b, int c, int d, int e );
  370|  int   bench4s( STRUCT3* s );
  371|  int   bench4t( int a, int b, int c, int d, int e, int f );
  372|  int   bench4x( int n );
  373|
  374|#define  bench4_loop   10000000
  375|
  376|void  bench4()
  377|{
  378|  int  i;
  379|  int  a;
  380|  STRUCT  s;
  381|  STRUCT2 ss;
  382|  STRUCT3 sss;
  383|
  384|#if 0
  385|bp();
  386|  for ( i = 0; i < bench4_loop; i++ )
  387|    a = bench4a( a );
  388|bp();
  389|  for ( i = 0; i < bench4_loop; i++ )
  390|    bench4b( &a );
  391|bp();
  392|  for ( i = 0; i < bench4_loop; i++ )
  393|    s.b = bench4a( s.b );
  394|bp();
  395|  for ( i = 0; i < bench4_loop; i++ )
  396|    bench4b( &s.b );
  397|bp();
  398|  for ( i = 0; i < bench4_loop; i++ )
  399|    bench4e( &s.b );
  400|bp();
  401|  for ( i = 0; i < bench4_loop; i++ )
  402|    bench4f( &s.b );
  403|bp();
  404|  bench4g( &s.b );
  405|bp();
  406|  bench4h( &s.b );
  407|bp();
  408|  for ( i = 0; i < bench4_loop; i++ )
  409|    bench4i( &s );
  410|bp();
  411|  for ( i = 0; i < bench4_loop; i++ )
  412|    bench4j( &s );
  413|bp();
  414|  bench4k( &s );
  415|bp();
  416|  bench4l( &s );
  417|#endif
  418|bp();
  419|  for ( i = 0; i < bench4_loop; i++ )
  420|    a = bench4m( &s );
  421|bp();
  422|  for ( i = 0; i < bench4_loop; i++ )
  423|    a = bench4n( 1,2 );
  424|bp();
  425|  for ( i = 0; i < bench4_loop; i++ )
  426|    a = bench4o( &ss );
  427|bp();
  428|  for ( i = 0; i < bench4_loop; i++ )
  429|    a = bench4p( 1,2,3,4 );
  430|bp();
  431|  for ( i = 0; i < bench4_loop; i++ )
  432|    a = bench4q( &sss );
  433|bp();
  434|  for ( i = 0; i < bench4_loop; i++ )
  435|    a = bench4r( 1,2,3,4,5 );
  436|bp();
  437|  for ( i = 0; i < bench4_loop; i++ )
  438|    a = bench4s( &sss );
  439|bp();
  440|  for ( i = 0; i < bench4_loop; i++ )
  441|    a = bench4t( 1,2,3,4,5,6 );
  442|bp();
  443|}
  444|
  445|
  446|int  bench4a( int a )
  447|{
  448|  return  bench4x( a );
  449|}
  450|
  451|void  bench4b( int* a )
  452|{
  453|  *a = bench4x( *a );
  454|}
  455|
  456|void  bench4e( int* a )
  457|{
  458|  *a = bench4x( *a );
  459|}
  460|
  461|void  bench4f( int* a )
  462|{
  463|  int  aa = *a;
  464|
  465|  aa = bench4x( aa );
  466|
  467|  *a = aa;
  468|}
  469|
  470|void  bench4g( int* a )
  471|{
  472|  int  i;
  473|
  474|  for ( i = 0; i < bench4_loop; i++ )
  475|    *a = bench4x( *a );
  476|}
  477|
  478|void  bench4h( int* a )
  479|{
  480|  int  i;
  481|  int  aa = *a;
  482|
  483|  for ( i = 0; i < bench4_loop; i++ )
  484|    aa = bench4x( aa );
  485|  *a = aa;
  486|}
  487|
  488|void  bench4i( STRUCT* s )
  489|{
  490|  s->b = bench4x( s->b );
  491|}
  492|
  493|void  bench4j( STRUCT* s )
  494|{
  495|  int  b = s->b;
  496|
  497|  b = bench4x( b );
  498|  s->b = b;
  499|}
  500|
  501|void  bench4k( STRUCT* s )
  502|{
  503|  int  i;
  504|
  505|  for ( i = 0; i < bench4_loop; i++ )
  506|    s->b = bench4x( s->b );
  507|}
  508|
  509|void  bench4l( STRUCT* s )
  510|{
  511|  int  i;
  512|  int  b = s->b;
  513|
  514|  for ( i = 0; i < bench4_loop; i++ )
  515|    b = bench4x( b );
  516|  s->b = b;
  517|}
  518|
  519|int   bench4m( STRUCT* s )
  520|{
  521|  return  s->a + s->b;
  522|}
  523|
  524|int   bench4n( int a, int b )
  525|{
  526|  return  a + b;
  527|}
  528|
  529|int   bench4o( STRUCT2* s )
  530|{
  531|  return  s->a + s->b + s->c + s->d;
  532|}
  533|
  534|int   bench4p( int a, int b, int c, int d )
  535|{
  536|  return  a + b + c + d;
  537|}
  538|
  539|int   bench4q( STRUCT3* s )
  540|{
  541|  return  s->a + s->b + s->c + s->d + s->e;
  542|}
  543|
  544|int   bench4r( int a, int b, int c, int d, int e )
  545|{
  546|  return  a + b + c + d + e;
  547|}
  548|
  549|int   bench4s( STRUCT3* s )
  550|{
  551|  return  s->a + s->b + s->c + s->d + s->e + s->f;
  552|}
  553|
  554|int   bench4t( int a, int b, int c, int d, int e, int f )
  555|{
  556|  return  a + b + c + d + e + f;
  557|}
  558|
  559|int  bench4x( int n )
  560|{
  561|  return  n;
  562|}
  563|
  564|
  565|/************************************************************************
  566|*  <<< 関数とマクロの比較、レジスタ変数の比較 [bench5()]>>>
  567|*【内容】
  568|*・関数呼び出しとマクロ展開の比較
  569|*・レジスタ変数を使用する場合としない場合の比較
  570|*・様々な処理内容による比較
  571|*【結果】
  572|*・レジスタ変数を使うと、機械語長が小さくなります。(2〜4byte)
  573|*・マクロでも、レジスタ変数を引数に渡さなければ、速くなりません。
  574|*・構造体メンバアクセス(case F, G) をマクロにすると、機械語長が小さく
  575|*  なります(2〜8byte)
  576|*・if, while を含む(case C, D)をマクロにすると、機械語長が特に大きく
  577|*  なります(8〜16byte)
  578|*・配列にアクセスするループは、ST or LD 命令のウェイトのため、
  579|*  マクロにしても仕方が無い。
  580|*・格納するメンバ変数が多いほど、マクロにする効果があります。(case G,H)
  581|*・引数は、参照に限りデフォルトでレジスタ変数になっています
  582|*・ループ変数は、必ずレジスタ変数になります
  583|*・構造体への格納は(ローカルでも)必ず ST 命令になります
  584|*・最適化をかけると、単純な演算(case A)が速くなります。
  585|*・最適化をかけると、ループを含むマクロ(関数)の機械語長が増え幅が
  586|*  小さくなります
  587|*【結論】
  588|*・マクロにする場合、レジスタ変数を考えないと性能が出ない
  589|*・case Aは、マクロにすると最適化がよくかかる
  590|*
  591|*【データ】
  592|*(コンパイラ=GHS, 最適化=なし)
  593|*  ケース   | 機械語長F 機械語長L  処理時間
  594|*  ------------------------------------------------
  595|*   afs  |     26         8       2.452943  **********
  596|*   ams  |     28        --       2.452943  **********
  597|*   afr  |     22         8       1.717141  *******
  598|*   amr  |     20        --       0.909075  ****
  599|*  ------------------------------------------------
  600|*   bfs  |     22        16       2.452944  **********
  601|*   bms  |     28        --       2.452943  **********
  602|*   bfr  |     --        --       --------
  603|*   bmr  |     --        --       --------
  604|*  ------------------------------------------------
  605|*   cfs  |     26        18       2.452944  **********
  606|*   cms  |     42        --       2.452944  **********
  607|*   cfr  |     22        18       2.121174  ********
  608|*   cmr  |     30                 1.313107  *****
  609|*  ------------------------------------------------
  610|*   dfs  |     30        18       3.066179  ****************
  611|*   dms  |     42        --       3.066179  ****************
  612|*   dfr  |     28        18       3.066179  ****************
  613|*   dmr  |     38        --       3.066179  ****************
  614|*  ------------------------------------------------
  615|*   efs  |     26        16       0.833319  *****
  616|*   ems  |     34        --       0.744936  ****
  617|*   efr  |     22        16       0.833319  *****
  618|*   emr  |     30        --       0.744936  ****
  619|*  ------------------------------------------------
  620|*   ffs  |     26         6       2.452944  **********
  621|*   fms  |     22        --       2.452943  **********
  622|*   ffr  |     24         6       1.515125  ******
  623|*   fmr  |     18        --       0.707059  ***
  624|*  ------------------------------------------------
  625|*   gfs  |     28        10       4.905885  ***************
  626|*   gms  |     26        --       4.905885  ***************
  627|*   gfr  |     26        10       4.905886  ***************
  628|*   gmr  |     22        --       4.905885  ***************
  629|*  ------------------------------------------------
  630|*   hfs  |     36        22      12.264713  ******************
  631|*   hms  |     38        --       9.811770  *************
  632|*   hfr  |     32        22      12.264713  ******************
  633|*   hmr  |     30        --       9.811770  *************
  634|*(コンパイラ=GHS, 最適化=あり)
  635|*  ケース   | 機械語長F 機械語長L  処理時間
  636|*  ------------------------------------------------
  637|*   afs  |     26         6       2.452944  **********
  638|*   ams  |     24        --       2.452944  **********
  639|*   afr  |     22         6       1.515124  ******
  640|*   amr  |     16        --       0.606050  **
  641|*  ------------------------------------------------
  642|*   bfs  |     22        12       2.452944  **********
  643|*   bms  |     24        --       2.452943  **********
  644|*   bfr  |     --        --       --------
  645|*   bmr  |     --        --       --------
  646|*  ------------------------------------------------
  647|*   cfs  |     26        18       2.452944  **********
  648|*   cms  |     32        --       2.452944  **********
  649|*   cfr  |     22        18       2.121174  ********
  650|*   cmr  |     30                 1.313107  *****
  651|*  ------------------------------------------------
  652|*   dfs  |     24        18       3.066180  ****************
  653|*   dms  |     36        --       3.066179  ****************
  654|*   dfr  |     22        18       3.066180  ****************
  655|*   dmr  |     32        --       3.066179  ****************
  656|*  ------------------------------------------------
  657|*   efs  |     26        16       0.858572  *****
  658|*   ems  |     34        --       0.744937  ****
  659|*   efr  |     22        16       0.833319  *****
  660|*   emr  |     30        --       0.744937  ****
  661|*  ------------------------------------------------
  662|*   ffs  |     26         6       2.452944  **********
  663|*   fms  |     22        --       2.452943  **********
  664|*   ffr  |     24         6       1.616133  *******
  665|*   fmr  |     18        --       0.707058  ***
  666|*  ------------------------------------------------
  667|*   gfs  |     28        10       4.905887  ***************
  668|*   gms  |     26        --       4.905886  ***************
  669|*   gfr  |     26        10       4.905886  ***************
  670|*   gmr  |     22        --       4.905885  ***************
  671|*  ------------------------------------------------
  672|*   hfs  |     36        22      12.264713  ******************
  673|*   hms  |     38        --       9.811771  *************
  674|*   hfr  |     32        22      12.264713  ******************
  675|*   hmr  |     30        --       9.811770  *************
  676|*(機械語長F は、関数全体のバイト数、機械語長L は、サブ関数内のバイト数)
  677|*************************************************************************/
  678|int  bench5af( int n )  {  return  n*2; }
  679|#define  bench5am( n )  ((n)*2)
  680|
  681|void  bench5bf( int* n )  { *n = *n * 2; }
  682|#define  bench5bm( n )    (*(n)= *(n) * 2)
  683|
  684|int  bench5cf( int n )  {  return  (n == 0 ? n<<1 : n+1); }
  685|#define  bench5cm( n )  ((n) == 0 ? (n)<<1 : (n)+1)
  686|
  687|void  bench5df( int* a, int n )
  688|  { int*  over = a+10;  while ( a < over )  { *a = n;  a++; } }
  689|#define  bench5dm( a,n ) \
  690|  { int* p=(a); int* over =p+10;  while(p < over) { *p = (n);  p++; } }
  691|
  692|int  bench5ef( int n )
  693|  { int  i;  int  nn = n;  for ( i=0; i<10; i++ )  nn += i;  return  nn;}
  694|#define  bench5em( n, ret ) \
  695|  { int  i;  int  nn = (n);  for ( i=0; i<10; i++ )  nn += i;  (ret) = nn;}
  696|int  bench5efr( int n )
  697|  { register int  i;  register int  nn = n; \
  698|    for ( i=0; i<10; i++ )  nn += i;  return  nn;}
  699|#define  bench5emr( n, ret ) \
  700|  { register int  i;  register int  nn = (n);  \
  701|    for ( i=0; i<10; i++ )  nn += i;  (ret) = nn;}
  702|
  703|int  bench5ff( STRUCT* s )  {  return  s->b; }
  704|#define  bench5fm( s )  ( (s)->b )
  705|
  706|void  bench5gf( STRUCT* s, int x, int y )  {  s->a = x;  s->b = y; }
  707|#define  bench5gm( s, x, y )  ( (s)->a = (x), (s)->b = (y) )
  708|
  709|void  bench5hf( STRUCT2* s, int x, int y, int xx, int yy )
  710|  {  s->a = x;  s->b = y;  s->c = xx;  s->d = yy;  }
  711|#define  bench5hm( s, x, y, xx, yy ) \
  712|  ( (s)->a = (x), (s)->b = (y), (s)->c = (xx), (s)->d = (yy) )
  713|
  714|#define  bench5_loop   10000000
  715|
  716|void  bench5()
  717|{
  718|  int  i;
  719|  register int  r;
  720|  int  n;
  721|  STRUCT   s;
  722|  STRUCT2  ss;
  723|
  724|bp();
  725|  for ( i=0; i < bench5_loop; i++ )
  726|    n = bench5af( n );
  727|bp();
  728|  for ( i=0; i < bench5_loop; i++ )
  729|    n = bench5am( n );
  730|bp();
  731|  for ( i=0; i < bench5_loop; i++ )
  732|    r = bench5af( r );
  733|bp();
  734|  for ( i=0; i < bench5_loop; i++ )
  735|    r = bench5am( r );
  736|bp();
  737|  for ( i=0; i < bench5_loop; i++ )
  738|    bench5bf( &n );
  739|bp();
  740|  for ( i=0; i < bench5_loop; i++ )
  741|    bench5bm( &n );
  742|bp();
  743|  for ( i=0; i < bench5_loop; i++ )
  744|    n = bench5cf( n );
  745|bp();
  746|  for ( i=0; i < bench5_loop; i++ )
  747|    n = bench5cm( n );
  748|bp();
  749|  for ( i=0; i < bench5_loop; i++ )
  750|    r = bench5cf( r );
  751|bp();
  752|  for ( i=0; i < bench5_loop; i++ )
  753|    r = bench5cm( r );
  754|bp();
  755|  for ( i=0; i < bench5_loop>>3; i++ )
  756|    bench5df( a, n );
  757|bp();
  758|  for ( i=0; i < bench5_loop>>3; i++ )
  759|    bench5dm( a, n );
  760|bp();
  761|  for ( i=0; i < bench5_loop>>3; i++ )
  762|    bench5df( a, r );
  763|bp();
  764|  for ( i=0; i < bench5_loop>>3; i++ )
  765|    bench5dm( a, r );
  766|bp();
  767|  for ( i=0; i < bench5_loop>>3; i++ )
  768|    n = bench5ef( n );
  769|bp();
  770|  for ( i=0; i < bench5_loop>>3; i++ )
  771|    bench5em( n, n );
  772|bp();
  773|  for ( i=0; i < bench5_loop>>3; i++ )
  774|    r = bench5efr( r );
  775|bp();
  776|  for ( i=0; i < bench5_loop>>3; i++ )
  777|    bench5emr( r, r );
  778|bp();
  779|  for ( i=0; i < bench5_loop; i++ )
  780|    n = bench5ff( &s );
  781|bp();
  782|  for ( i=0; i < bench5_loop; i++ )
  783|    n = bench5fm( &s );
  784|bp();
  785|  for ( i=0; i < bench5_loop; i++ )
  786|    r = bench5ff( &s );
  787|bp();
  788|  for ( i=0; i < bench5_loop; i++ )
  789|    r = bench5fm( &s );
  790|bp();
  791|  for ( i=0; i < bench5_loop; i++ )
  792|    bench5gf( &s, n, n );
  793|bp();
  794|  for ( i=0; i < bench5_loop; i++ )
  795|    bench5gm( &s, n, n );
  796|bp();
  797|  for ( i=0; i < bench5_loop; i++ )
  798|    bench5gf( &s, r, r );
  799|bp();
  800|  for ( i=0; i < bench5_loop; i++ )
  801|    bench5gm( &s, r, r );
  802|bp();
  803|  for ( i=0; i < bench5_loop; i++ )
  804|    bench5hf( &ss, n, n, n, n );
  805|bp();
  806|  for ( i=0; i < bench5_loop; i++ )
  807|    bench5hm( &ss, n, n, n, n );
  808|bp();
  809|  for ( i=0; i < bench5_loop; i++ )
  810|    bench5hf( &ss, r, r, r, r );
  811|bp();
  812|  for ( i=0; i < bench5_loop; i++ )
  813|    bench5hm( &ss, r, r, r, r );
  814|bp();
  815|}
  816|
  817|
  818|/************************************************************************
  819|*  <<< mul 命令を mac3 命令に置き換えて比較 [benchX()]>>>
  820|*【結果】
  821|*・処理時間に差がでなかった(計測方法に問題があるかも)
  822|*************************************************************************/
  823|#if 0
  824|void  benchX()
  825|{
  826|  register int  i, j, k;
  827|  int  w;
  828|
  829|bp();
  830|
  831|/* このアセンブラコードは、GHS -S オプションで出力されたものに、*/
  832|/* mul 命令を mac3 命令に置き換えたものです */
  833|/* 実行スピードは同じです。コードサイズが(たった)2byte 小さくなります */
  834|__asm("		mov	0,r9");
  835|__asm("		jbr	L21");
  836|__asm("	L20:");
  837|__asm("		mov	0,r8");
  838|__asm("		jbr	L25");
  839|__asm("	L24:");
  840|__asm("		mov	r8,r14");
  841|__asm("		movea	1080,zero,r16");
  842|__asm("		mul	r9,r16");
  843|__asm("		add	r16,r14");
  844|__asm("		movea	360,zero,r13");
  845|__asm("	--	mul	r9,r13");
  846|__asm("	--	mov	r8,r17");
  847|__asm("	--	add	r13,r17");
  848|__asm("	        mov     r8,r17");
  849|__asm("		mac3	r9,r13,r17");
  850|__asm("	--");
  851|__asm("		shl	2,r17");
  852|__asm("		movhi	pidhi(_c),gp,r15");
  853|__asm("		add	r15,r17");
  854|__asm("		add	1,r8");
  855|__asm("		st.w	r14,pidlo(_c)[r17]");
  856|__asm("	L25:");
  857|__asm("		movea	360,zero,r14");
  858|__asm("		cmp	r14,r8");
  859|__asm("		ablt	L24");
  860|__asm("		add	1,r9");
  861|__asm("	L21:");
  862|__asm("		movea	655,zero,r13");
  863|__asm("		cmp	r13,r9");
  864|__asm("		ablt	L20");
  865|
  866|bp();
  867|  w = 1080;
  868|  for ( i = 0; i < 655; i++ ) {
  869|    for ( j = 0; j < 360; j++ ) {
  870|      k = j;
  871|      k = i * w + k;  /* c[i][j]で MUL 使用、i*w で MUL 使用 */
  872|      c[i][j] = k;  /* c[i][j]で MUL 使用、i*w で MUL 使用 */
  873|    }
  874|  }
  875|bp();
  876|}
  877|#endif
  878|
  879|