【问题标题】:Calling with Arguments versus using Globals in C使用参数调用与在 C 中使用全局变量
【发布时间】:2015-08-03 18:33:16
【问题描述】:

我对 x86 汇编有相当的了解,并且我知道当调用一个函数时,所有参数都会被压入堆栈。

我有一个函数,它基本上遍历一个 8 x 8 数组,并根据数组中的值调用一些函数。这些函数调用中的每一个都涉及传递 6-10 个参数。这个程序运行时间很长,是一个国际象棋AI,但是这个功能需要20%的运行时间。

所以我想我的问题是,我该怎么做才能让我的函数以更快的方式访问他们需要的变量?

int row,col,i;  
determineCheckValidations(eval_check, b, turn);
int * eval_check_p = &(eval_check[0][0]);

for(row = 0; row < 8; row++){
    for(col = 0; col < 8; col++, eval_check_p++){
        if (b->colors[row][col] == turn){
            int type = b->types[row][col];
            if (type == PAWN)
                findPawnMoves(b,moves_found,turn,row,col,last_move,*eval_check_p);
            else if (type == KNIGHT)
                findMappedNoIters(b,moves_found,turn,row,col,*move_map_knight, 8, *eval_check_p);
            else if (type == BISHOP)
                findMappedIters(b,moves_found,turn,row,col,*move_map_bishop, 4, *eval_check_p);
            else if (type == ROOK)
                findMappedIters(b,moves_found,turn,row,col,*move_map_rook, 4, *eval_check_p);
            else if (type == QUEEN)
                findMappedIters(b,moves_found,turn,row,col,*move_map_queen, 8, *eval_check_p);
            else if (type == KING){
                findMappedNoIters(b,moves_found,turn,row,col,*move_map_king, 8, *eval_check_p);
                findCastles(b,moves_found,turn,row,col);
            }
        }
    }
}

所有代码都可以找到@https://github.com/AndyGrant/JChess/tree/master/_Core/_Scripts

个人资料样本:

  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 20.00      1.55     1.55  2071328     0.00     0.00  findAllValidMoves
 14.84      2.70     1.15 10418354     0.00     0.00  checkMove
 10.06      3.48     0.78  1669701     0.00     0.00  encodeBoard
  7.23      4.04     0.56 10132526     0.00     0.00  findMappedIters
  6.84      4.57     0.53  1669701     0.00     0.00  getElement
  6.71      5.09     0.52 68112169     0.00     0.00  createNormalMove

【问题讨论】:

  • 是什么让您认为是参数传递导致了性能问题?可能还有很多其他的东西。
  • 这个函数可以内联吗?这将删除大量堆栈处理,并可能将一些参数保留为寄存器......
  • 是什么让您认为传递参数是您的性能瓶颈?你分析过你的代码吗?如何?什么?你试过内联吗?你的论据是什么?几个整数?或者您是否通过值传递了一个巨大的结构?函数中还会发生什么?
  • @AndrewGrant “只有一个循环和函数调用”。著名的遗言 :-) 猜测可能不是解决这个问题的好方法。更深入地分析您的代码(不仅仅是在函数级别)。
  • @AndrewGrant 20% 的运行时间,但调用次数的百分比是多少?那是自我时间还是总时间?是的,循环、分支和函数调用......这是大量的事情。

标签: c assembly arguments


【解决方案1】:

您在分析方面做得很好。您需要采用最坏情况下的功能并更详细地对其进行分析。

您可能想在分析时尝试不同的编译器优化设置。

尝试一些常见的优化技术,例如循环展开和从循环中分解出不变量。

在设计函数时考虑到处理器的数据缓存,您可能会获得一些改进。在网上搜索“优化数据缓存”。

如果功能正常,我建议发帖到 CodeReview@StackExchange.com。

不要假设任何事情。

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    相关资源
    最近更新 更多