我创建了以下代码来计算逻辑门(AND、OR、NOT)的结果。该函数将用于从网表文件中读取电路的电路仿真中。一个电路最多可以包含 50000 个逻辑门。
基于这个函数在模拟过程中经常被调用的事实,我想知道是否可以用另一种方式实现它,以便生成的机器代码更有效率?
一个逻辑门可以有两个以上的输入(除非只有一个输入)但大多数逻辑门只有两个。所以我考虑测试两个输入,然后写这样的东西:return input->predecessors[0]->result && return input->predecessors[1]->result;
and 返回输入->predecessors[0]->result || return input->predecessors[1]->result;
但这可能会引入新的分支。输入的数量可以直接存储在Node
中,以防止调用size()
方法。
#include <vector>
enum class NodeType { NOT, AND, OR };
struct Node {
NodeType type;
bool result;
std::vector<Node *> predecessors;
};
bool evaluate(Node *input) {
switch (input->type) {
case NodeType::NOT: {
return !input->predecessors[0]->result;
}
case NodeType::AND: {
bool result = true;
for (const auto &node : input->predecessors) {
result = result && node->result;
}
return result;
}
case NodeType::OR: {
bool result = false;
for (const auto &node : input->predecessors) {
result = result || node->result;
}
return result;
}
};
};
最佳答案
我很想获取第一个输入并将其状态合并到 switch()
中;喜欢:
bool result = input->predecessors[0];
switch((input->type << 1) | result) {
case (NodeType::NOT << 1) | false:
return true;
case (NodeType::NOT << 1) | true:
return false;
case (NodeType::AND << 1) | false:
return false;
case (NodeType::OR << 1) | true:
return true;
case (NodeType::AND << 1) | true: {
for (const auto &node : input->predecessors) { // Note: Can skip 1st iteration
result = result && node->result;
if(result == false) {
return false;
}
}
return true;
}
case (NodeType::OR << 1) | false:
for (const auto &node : input->predecessors) { // Note: Can skip 1st iteration
result = result || node->result;
if(result == true) {
return true;
}
}
return false;
}
希望编译器能够将其转换为跳转表(例如,单个“jmp [table+rax*8]
”指令替换所有 switch()
和其余代码的一半)。
警告:要使其正常工作,您必须确保 input->predecessors[0]
使用 1 表示“true”(并且没有其他值用于表示 true)。如果这是一个潜在的问题;你可以使用 bool result = !!input->predecessors[0];
关于c++ - 逻辑门的快速计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58883820/