【问题标题】:Connection between ternary logic and mux logic?三元逻辑和复用逻辑之间的联系?
【发布时间】:2011-02-27 12:18:05
【问题描述】:

我正在用 C 语言实现一个计算机模拟器,挑战不使用条件(即不使用 if/else、switch/case、while/for 等)。我正在模拟的硬件中有很多多路复用器,所以如果我可以使用条件三元逻辑运算符会很好。所以,我的问题是:C 编译器是从三元逻辑运算符创建 MUX 逻辑,还是创建分支?

例子:

int a, b, q, r;
/* Ternary logic */
r = q ? a : b;
/* MUX equivalent logic */
r = ( q & a ) | ( (~q) & b )
/* Branch equivalent logic */
if (q) r = a; else r = b;

【问题讨论】:

    标签: c compiler-construction ternary-operator


    【解决方案1】:

    三元运算符相当于一个分支:即未返回的值不被评估。

    我不知道你有多少限制,所以请注意布尔运算符 &&|| 不评估他们的第二个参数,结果可以从第一个参数确定。

    (请注意,“MUX”行与其他两个表达式没有太大不同:它根据 q 中相应位的值从 a 或 b 中选择位,它不会根据 q 中相应位的值选择 a 或 b如果 q 是否为空;编辑:更糟糕的是:您使用的是 !q 而不是 ~q...)。

    【讨论】:

    • 1.我知道三元运算符等同于分支,如上所述。我要问的是,“编译器是否在汇编级别生成分支?” 2.我没有发现&&和||有什么用处到目前为止的布尔运算符。我会记住你的见解。 3. 我对你使用“null”这个词感到困惑。但你是对的,在大多数情况下我应该切换到 ~ (这是一个简单的 1 位值示例,但我会编辑它)。
    • 1.是(它不能评估另一个分支)。 3. 零
    • 啊!我明白你现在的意思了。谢谢!
    【解决方案2】:

    C 编译器从三元语句创建分支。

    使用飞思卡尔的 Codewarrior IDE,我编译了以下 C 程序:

    int a, b, q, r;    
    void main(void) {    
      a = 0;    
      b = 1;    
      q = 0;    
      r = q ? a : b;    
    ..
    ..    
    }
    

    三元语句对应的程序集如下:

    ...
    LDX    0x1104 ; load val[q] into register x    
    BNE    *+4    ; branch to abs addr 0xC016 if val[q]==a    
    BRA    *+5    ; branch to abs addr 0xC019 if val[q]!=a
    ...
    

    【讨论】:

      【解决方案3】:

      通常,会创建分支逻辑,但如果您对两个值都进行评估,那么很可能在没有任何分支的情况下进行三元运算。考虑一下:

      #include <stdio.h>
      
      static inline int isel(int cond, int a, int b)
      {
         int mask = cond | (-cond);
         mask >>= 31;
         return (b & mask) | (a & ~mask);
      }
      
      int main(void)
      {
         printf("1 ? 3 : 4 => %d\n", isel(1, 3, 4));
         printf("0 ? 3 : 4 => %d\n", isel(0, 3, 4));
         printf("-1 ? 3 : 4 => %d\n", isel(-1, 3, 4));
         return 0;
      }
      

      此代码假定有符号数的右移将符号扩展,并且 sizeof(int) == 4。 一些处理器可以将 isel() 作为汇编指令执行。但是,这两个值都会被计算,而三元 ?: 不会。

      根据情况,编译器通常会尝试做最快的事情,要么分支以避免冗余计算,要么在三元表达式中的值很简单的情况下进行这种逻辑。

      【讨论】:

      • 酷!我使用带有位字段的结构来对位信号进行符号扩展,但这也可以,谢谢!我最初认为编译器会不惜一切代价避免分支,但正如您所说,检查“冗余计算”也是有意义的。
      猜你喜欢
      • 1970-01-01
      • 2012-03-06
      • 2012-08-07
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多