謎's キッチン

謎のひとりごと。Amazon欲しい物リストはこちら: https://www.amazon.co.jp/hz/wishlist/ls/CCPOV7C6JTD2

ntzの高速化続き

重ねたテーブル使ってみた。遅かったのでインラインアセンブラで書き直したら早くなった。コンパイラは当てにできないなぁ。

invariant ubyte[152] table=[
  0, 0, 1, 0, 2, 0, 8, 9, 3,10, 0,16,17,11,18, 0, 4, 0,19, 0, 0,12, 0, 0,24,25,20,26, 0, 0, 0,27,
  5, 0, 0, 0, 0,13, 0,28, 0, 0,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,29, 0, 0, 0, 0, 0, 0, 0, 0,
  6, 0, 0, 0, 0,14, 0, 0, 0, 0,22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,30, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  7, 0, 0, 0, 0,15, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,31
];

uint ntz(bool zero=true)(uint x){
  asm{
    naked;
  };
  static if(!zero)
    assert(x);
  else
    asm{
      test EAX, EAX;
      jne n;
      mov EAX, 32;
      ret;
    };
  n:

  asm{
    mov ECX, EAX;
    neg ECX;
    and ECX, EAX;

    movzx EAX, CL;
    mov   AL, byte ptr table[EAX];
    movzx EDX, CH;
    or    AL, byte ptr table[EDX+0x5];
    shr ECX, 16;

    mov  DL, CL;
    or   AL, byte ptr table[EDX+0xa];
    mov  DL, CH;
    or   AL, byte ptr table[EDX+0x17];

    ret;
  };
}


ntzはx86ではbsf、gccではctz、linuxではffsってなってるようだ。何このバラバラ。