【发布时间】: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% 的运行时间,但调用次数的百分比是多少?那是自我时间还是总时间?是的,循环、分支和函数调用......这是大量的事情。