小编Mik*_*e S的帖子

我可以将此宏更改为内联函数而不会影响性能吗?

(编辑:让我们称之为"测量可能出错的经验教训."我仍然没有弄清楚究竟是什么导致了这种差异.)

Mark Crowne 找到了一个非常快速的整数平方根函数.至少在我的机器上使用GCC,它显然是我测试过的最快的整数平方根函数(包括来自标准库的Hacker's Delight,this page和floor(sqrt())中的函数.

清理格式化,重命名变量和使用固定宽度类型后,它看起来像这样:

static uint32_t mcrowne_isqrt(uint32_t val)
{
    uint32_t temp, root = 0;

    if (val >= 0x40000000)
    {
        root = 0x8000;
        val -= 0x40000000;
    }

    #define INNER_ISQRT(s)                              \
    do                                                  \
    {                                                   \
        temp = (root << (s)) + (1 << ((s) * 2 - 2));    \
        if (val >= temp)                                \
        {                                               \
            root += 1 << ((s)-1);                       \
            val -= temp;                                \
        }                                               \
    } while(0)

    INNER_ISQRT(15);
    INNER_ISQRT(14);
    INNER_ISQRT(13);
    INNER_ISQRT(12);
    INNER_ISQRT(11); …
Run Code Online (Sandbox Code Playgroud)

c++ macros performance inline sqrt

10
推荐指数
1
解决办法
904
查看次数

x86 eflags第18位(对齐检查)如何工作?(与检查386与486及更高版本相关.)

我已经读过如果可以修改eflags第18位(AC - 对齐检查),你知道CPU是486或更新.在386上,该位抵抗修改.

我从这个站点解除了以下汇编代码并添加了详尽的注释(保留了奇怪的语法):

asm
    mov  bx,sx            ; Save the stack pointer to bx (is sx a typo or a real register?).
    and  sp,$fffc         ; Truncate the stack pointer to a 4-byte boundary.
    pushfl                ; Push the eflags register to the stack.
    pop  eax              ; Pop it into eax.
    mov  ecx,eax          ; Save the original eflags value into ecx.
    xor  eax,$40000       ; Flip bit 18 in eax.
    push eax              ; Push eax to the stack.
    popfl                 ; Pop …
Run Code Online (Sandbox Code Playgroud)

x86 assembly flags alignment

5
推荐指数
1
解决办法
3108
查看次数

CPUID:为什么某些功能必须将MISC_ENABLE.LCMV设置为0?我可以暂时覆盖它吗?

我正在尝试使用CPUID,但是附加了一些字符串.根据sandpile.org 的CPUID页面,CPUID标准函数0000_0004h及以上仅在MISC_ENABLE.LCMV标志设置为0时才起作用.该标志是模型专用寄存器(MSR)1A0的第22位.显然,这种限制是由于Windows NT中的一个错误(感谢让我更轻松,微软;)).

我可以使用CPUID 0000_0001h(ecx标志,位3)测试LCMV标志的存在.假设它存在,究竟是什么,为什么它对CPUID有这样的影响?MSR 1A0是读/写寄存器还是只读?这样的专用寄存器如何使用汇编代码读/写?

如果寄存器在技术上是读/写,那么在将CPU22指令恢复到原始设置之前,在将CPU22指令的持续时间内将第22位复位为0是否安全?或者如果它设置不正确(即启用),我几乎搞砸了?

最后,sandpile使用了"只有在MISC_ENABLE.LCMV设置为0时才启用此级别.这是由于Windows NT错误." 如果由于这个原因特别禁用了一堆标准级别,那么这是否会反映在CPUID级别0000_000h的eax寄存器(最大支持的标准级别)的输出中?

Phew ......我认为就是这样.

x86 assembly x86-64 cpuid msr

4
推荐指数
1
解决办法
787
查看次数

标签 统计

assembly ×2

x86 ×2

alignment ×1

c++ ×1

cpuid ×1

flags ×1

inline ×1

macros ×1

msr ×1

performance ×1

sqrt ×1

x86-64 ×1