我想要在我的Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz机器上禁用所有的缓存级别,并使用Xen技术。我编写了一个工具,调用以下汇编代码来禁用/启用缓存并显示CR0寄存器的值。
case XENMEM_disable_cache:
__asm__ __volatile__(
"pushq %%rax\n\t"
"movq %%cr0,%%rax\n\t"
"orq $0x40000000,%%rax\n\t"
"movq %%rax,%%cr0\n\t"
"movq %%cr0, %0\n\t"
"wbinvd\n\t"
"popq %%rax"
: "=r"(cr0)
:
:);
// gdprintk(XENLOG_WARNING, "gdprintk:XENMEM_disable_cache disable cache!
// TODO IMPLEMENT\n");
printk("<1>printk: disable cache! cr0=%#018lx\n", cr0);
rc = 0;
break;
case XENMEM_enable_cache:
__asm__ __volatile__(
"pushq %%rax\n\t"
"movq %%cr0,%%rax\n\t"
"andq $0xffffffffbfffffff,%%rax\n\t" /*~0x4000000*/
"movq %%rax,%%cr0\n\t"
"movq %%cr0, %0\n\t"
"popq %%rax"
: "=r"(cr0)
:
:);
printk("<1>printk: enable cache; cr0=%#018lx\n", cr0);
rc = 0;
break;
case XENMEM_show_cache:
__asm__ __volatile__(
"pushq %%rax\n\t"
"movq %%cr0, %%rax\n\t"
"movq %%rax, %0\n\t"
"popq %%rax"
: "=r"(cr0)
:
:);
// gdprintk(XENLOG_WARNING, "gdprintk:XENMEM_show_cache_status! CR0 value is
// %#018lx\n", cr0);
printk("<1>printk: XENMEM_show_cache_status! CR0 value is %#018lx\n", cr0);
return (long)cr0;
这段代码可以编译并运行。当我运行“disable cache”代码后,系统变得异常缓慢,这证实缓存已经被禁用。此外,当我运行“disable cache”代码时,CR0的值显示CD位被设置。
然而,当我运行“show cache”代码时,输出显示无论是否禁用/启用缓存,CR0的CD位都是0。
我的问题是:
当缓存被禁用时,CR0寄存器的CD位(第30位)是否总是设置为1?
如果不是,那么我的代码一定有问题,请帮我指出错误。
答案:
以上代码只在运行代码的核心上设置了CR0寄存器的CD位。我们需要使用smp_call_function()在所有核心上调用代码!
我的新问题是:
如果我使用以上代码禁用缓存,然后再启用缓存,CR0的CD位会被清除。但是系统的性能仍然非常缓慢,就像缓存被禁用时一样。因此,对我来说好像启用缓存代码没有起作用?然而,既然CD位已经被清除,启用缓存代码应该起作用了!所以问题是:我需要等多久才能在启用缓存后拥有与禁用缓存前相同的性能?
顺便说一下,当我运行启用缓存代码时,printk输出显示CR0的CD位为0。
smp_call_function()
为每个核心调用禁用缓存代码?理论上可能会出现您的显示缓存代码在不同的处理器上运行的情况。我还建议您阅读英特尔的软件开发手册,第3卷,第11章(内存缓存控制),特别是第11.5.1节“缓存控制寄存器和位”。 - Iwillnotexist Idonotexistinclude/linux/smp.h
。 - Iwillnotexist Idonotexist