我正在编写一个使用包围体层次结构来加速光线追踪的小型光线追踪器。长话短说,我有一棵二叉树,我可能需要访问多个叶子。
当前我有一个左右两个孩子的节点,然后在 travel() 期间,如果某些条件,在此示例 intersect() 中,访问孩子:
class BoundingBoxNode{
BoundingBoxNode* left, *right;
void travel(param &p);
inline bool intersect(param &p){...};
};
void BoundingBoxNode::travel(param &p){
if(this->intersect(p)){
if(left)
left->travel(p);
if(right)
right->travel(p);
}
}
这种方法使用递归方法调用,但是,我需要尽可能优化这段代码......并且根据 IA-32 的优化参考手册,超过 16 的函数调用可能非常昂贵,所以我想这样做使用 while 循环而不是递归调用。但我不希望进行动态堆分配,因为这些很昂贵。所以我在想,也许我可以利用这样一个事实,即每次 while 循环从堆栈开始时都会处于相同的位置。在以下非常丑陋的黑客攻击中,我依靠 alloca() 始终分配相同的地址:
class BoundingBoxNode{
BoundingBoxNode* left, right;
inline void travel(param &p){
int stack_size = 0;
BoundingBoxNode* current = this;
while(stack_size >= 0){
BoundingBoxNode* stack = alloca(stack_size * 4 + 2*4);
if(current->intersect(p)){
if(current->left){
stack[stack_size] = current->left;
stack_size++;
}
if(current->right){
stack[stack_size] = current->right;
stack_size++;
}
}
stack_size--;
current = stack[stack_size];
}
};
inline bool intersect(param &p){...};
};
然而令人惊讶的是,这种方法似乎确实失败了:)但只要堆栈小于 4 或 5,它就可以工作......我也非常有信心这种方法是可能的,我只是真的认为我需要一些帮助来实现它正确。
那么如何从 C++ 手动操作堆栈,是否可以使用一些编译器扩展......或者我必须这样做是汇编程序,如果是这样,我如何编写汇编程序而不是可以用 GCC 和 ICC 编译.
我希望有人可以帮助我......我不需要一个完美的解决方案,只是一个黑客,如果它有效,它就足以达到这个目的:)
问候乔纳斯·芬尼曼·詹森