Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly x2APIC中的MSR性能_Assembly_X86_Intel_Interrupt Handling - Fatal编程技术网

Assembly x2APIC中的MSR性能

Assembly x2APIC中的MSR性能,assembly,x86,intel,interrupt-handling,Assembly,X86,Intel,Interrupt Handling,正如我们所知,在x2APIC中,我们使用MSR而不是xAPIC使用的MMIO。 但是根据我的测试,我发现MSR的访问速度比MMIO慢得多 例如,在我的环境中,我编写了一个简单的测试用例,如下所示: static __inline__ void __loApicWrite ( UINT32 * addr, UINT32 value ) { __asm__ volatile ( "movl %1, %0" : "=m" (*(addr)) : "

正如我们所知,在x2APIC中,我们使用MSR而不是xAPIC使用的MMIO。 但是根据我的测试,我发现MSR的访问速度比MMIO慢得多

例如,在我的环境中,我编写了一个简单的测试用例,如下所示:

static __inline__ void __loApicWrite
(
UINT32    * addr,
UINT32      value
)
{
__asm__ volatile
    (
    "movl    %1, %0"
    : "=m" (*(addr))
    : "ir" (value)
    );
}

void MSR_vs_MMIO(int way)
{
unsigned long a;
unsigned long b;
int i = 0;

msrReg = MSR_BASE_ADDRESS + (LOAPIC_ESR >> 4);

if (way == 0) /*MSR*/
    {
    for (i = 0; i < 1000; i++)
        {
        a = pentiumTscGet();    

        __asm__ volatile
        (
        "wrmsr\n"
        : : "c" (msrReg), "a"(0), "d" (0)
        );

        b =  pentiumTscGet();   

        if ( b > a ) 
            benchmark_record[i] = b - a ;
        }
    }

else         /*MMIO*/
    {
    for (i = 0; i < 1000; i++)
        {
        a =  pentiumTscGet();   

        __loApicWrite((UINT32 *)((0x82244000) + LOAPIC_ESR), 0);
        b =  pentiumTscGet();   

        if ( b > a )
            benchmark_record[i] = b - a ;
        }
    }

return;
static\uuuuu inline\uuuuu void\uuuu loApicWrite
(
UINT32*地址:,
UINT32值
)
{
__反复无常
(
移动%1,%0
:“=m”(*(地址))
:“ir”(值)
);
}
无效MSR_vs_MMIO(内部方式)
{
无符号长a;
无符号长b;
int i=0;
msrReg=MSR\U基地址+(LOAPIC\U ESR>>4);
如果(方式==0)/*MSR*/
{
对于(i=0;i<1000;i++)
{
a=奔腾TSGET();
__反复无常
(
“wrmsr\n”
:“c”(msrReg)、“a”(0)、“d”(0)
);
b=奔腾TSGET();
如果(b>a)
基准记录[i]=b-a;
}
}
else/*MMIO*/
{
对于(i=0;i<1000;i++)
{
a=奔腾TSGET();
__loApicWrite((UINT32*)((0x82244000)+loapicu ESR),0;
b=奔腾TSGET();
如果(b>a)
基准记录[i]=b-a;
}
}
返回;
}

如果我运行“MSR_vs_MMIO 0”,我得到的数字大约是310。 如果我运行“MSR_vs_MMIO 1”,我得到的数字大约是40

我在启用和禁用x2APIC的情况下在系统上进行测试。当我在启用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 0”,当我在禁用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 1”。然后我收集了数据,发现性能有很大的不同

因此,MMIO似乎比MSR访问快8倍左右

这个结果是否如预期的那样?《英特尔手册》(我搜索过但没有得到答案)中是否有任何文档描述x2APIC中的MSR和xAPIC中的MMIO之间的性能差异



谢谢。

假设您的系统以x2apic模式启动,APIC的MMIO接口将被禁用,因此您的MMIO代码实际上不会访问APIC。请参阅“英特尔SDM”第10.12.2节。

如果系统以x2apic模式启动,则APIC的MMIO接口将被禁用,因此MMIO代码实际上不会访问APIC。请参阅“英特尔SDM”第10.12.2节。

这可能与计时无关,但您的内联asm已损坏;)与此相关的是“WRMSR指令是一条串行化指令”(引用自指令集参考手册:))谢谢Jester,你能告诉我损坏的内联asm吗?你正在调零
eax
edx
,但没有告诉编译器,你需要对它们进行重击,或者更好,将输入作为
“a”(0)、“d”(0)
传递,并删除
movl
s。谢谢Jester,我将更新我的内联asm。顺便说一句,我检查了x2APIC规范,发现了一个声明:“为了在x2APIC模式下有效地访问APIC寄存器,在写入APIC寄存器时,WRMSR的序列化语义是宽松的。”。所以问题似乎不是由“序列化”引起的。你也可以考虑对各种不同的APIC寄存器的访问。它们可能不完全相同,制造商可能更可能提高正常操作中访问的寄存器的性能,而不是设置/初始化代码或错误情况。这可能与计时无关,但您的内联asm已损坏;)与此相关的是“WRMSR指令是一条串行化指令”(引用自指令集参考手册:))谢谢Jester,你能告诉我损坏的内联asm吗?你正在调零
eax
edx
,但没有告诉编译器,你需要对它们进行重击,或者更好,将输入作为
“a”(0)、“d”(0)
传递,并删除
movl
s。谢谢Jester,我将更新我的内联asm。顺便说一句,我检查了x2APIC规范,发现了一个声明:“为了在x2APIC模式下有效地访问APIC寄存器,在写入APIC寄存器时,WRMSR的序列化语义是宽松的。”。所以问题似乎不是由“序列化”引起的。你也可以考虑对各种不同的APIC寄存器的访问。它们可能不完全相同,制造商可能更可能改进正常操作中访问的寄存器的性能,而不是设置/初始化代码或错误情况。感谢prl的评论。实际上,我在启用和禁用x2APIC的情况下在系统上进行测试。当我在启用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 0”,当我在禁用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 1”。然后我收集数据,发现性能有很大的不同。您应该在问题中说您在两个测试之间重新启动。@prl这也是我在设备管理器或上看不到APIC的原因!我的卡比湖系统上的pcitree(因为它使用x2APIC)感谢prl的评论。实际上,我在启用和禁用x2APIC的情况下在系统上进行测试。当我在启用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 0”,当我在禁用x2APIC的情况下启动系统时,我运行测试“MSR\u vs_MMIO 1”。然后我收集数据,发现性能有很大的不同。您应该在问题中说您在两个测试之间重新启动。@prl这也是我在设备管理器或上看不到APIC的原因!我的kaby lake系统上的pcitree(因为它使用x2APIC)