x86/x86_64体系结构的每个现代高性能CPU都有一些数据缓存层次结构:L1,L2,有时是L3(在极少数情况下是L4),从/向主RAM加载的数据缓存在其中一些中.
有时程序员可能希望某些数据不会缓存在某些或所有缓存级别中(例如,当想要memset 16 GB的RAM并将某些数据保留在缓存中时):有一些非时间(NT)指令用于这就像MOVNTDQA(/sf/answers/2596471/ http://lwn.net/Articles/255364/)
但有没有一种编程方式(对于某些AMD或Intel CPU系列,如P3,P4,Core,Core i*,......)完全(但暂时)关闭部分或全部级别的缓存,以改变每个内存的方式访问指令(全局或某些应用程序/ RAM区域)使用内存层次结构?例如:关闭L1,关闭L1和L2?或更改每次存储器访问类型CR0 ??? SDM vol3a页的"未缓存的" UC(CD + NW位423 424,425和" 仅适用于基于处理器的三级缓存禁止标志,位在IA32_MISC_ENABLE MSR 6(可用英特尔NetBurst微体系结构) - 允许禁用和启用L3缓存,独立于L1和L2缓存.").
我认为这样的行动将有助于保护数据免受缓存侧通道攻击/泄漏,如窃取AES密钥,隐蔽缓存通道,Meltdown/Spectre.虽然这种禁用会产生巨大的性能成本.
PS:我记得多年前在一些技术新闻网站上发布的这样一个程序,但现在找不到它.将一些神奇的值写入MSR只是一个Windows exe,并使每个Windows程序运行得很慢.缓存关闭直到重新启动或直到使用"撤消"选项启动程序.
我正在尝试编写一个可以读取msr寄存器的简单应用程序,并从用户空间运行此应用程序.
我已经加载了msr模块,并为每个人提供了对/ dev/cpu/*/msr的读取权限.但是仍然用户无法访问这些文件,但root可以.
权限如下所示:
crw-r--r-- 1 root root 202, 0 sep 6 17:55 /dev/cpu/0/msr
crw-r--r-- 1 root root 202, 1 sep 6 17:55 /dev/cpu/1/msr
crw-r--r-- 1 root root 202, 2 sep 6 17:55 /dev/cpu/2/msr
crw-r--r-- 1 root root 202, 3 sep 6 17:55 /dev/cpu/3/msr
Run Code Online (Sandbox Code Playgroud)
当我尝试从用户空间读取这些文件时,我一直收到"不允许操作"错误消息,但当root尝试访问它们时工作正常.我究竟做错了什么?我在Ubuntu 13.04上使用内核版本3.11.0.
首先,我不知道我是否应该在这里问这个问题,或者在 Electronics StackExchange 中问这个问题,所以如果您认为我应该在那里问这个问题,请告诉我。
我对测量 Intel CPU 中每个 CPU 核心的能耗感兴趣。我已阅读 Intel 的 Intel 64 开发人员手册,据我了解,RAPL 将提供以下方面的能耗估算:
这表明我能期望的最好结果是 CPU 中所有内核的集体能耗值。然而,我也知道“RAPL不是模拟功率计,而是使用软件功率模型”,根据https://01.org/blogs/2014/running-average-power-limit-%E2%80 %93-rapl。
我想知道的是,这个模型的工作方式是已知的还是公开的?并且,是否可以使用 RAPL 或其他接口提供的指标来估计各个核心功耗?我知道,如果英特尔不通过 RAPL 提供此信息,则可能无法获得它,但我想至少找到一个证实这一点的来源。
感谢您的帮助!
我在Haswell CPU(Intel Core i7-4790)上安装了perf.但是"性能列表"不包括"停滞 - 循环 - 前端"和"停滞循环 - 后端".我检查了http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html,但没有找到与表19中的停滞循环后端相关的性能事件 - 7(第四代英特尔酷睿处理器的处理器核心中的非架构性能事件).
所以我的问题是:如何使用Haswell CPU内核中的perf或其他工具来测量停滞循环后端.内核是3.19,perf版本也是3.19.
谢谢
尝试在我的Core i7系统中禁用硬件预取程序时,我收到错误.我按照链接按照方法如何以编程方式禁用硬件预取?
在我的系统中
grep -i msr/boot/config - $(uname -r)
CONFIG_X86_DEBUGCTLMSR = Y
CONFIG_X86_MSR = Y
CONFIG_SCSI_ARCMSR =米
这是我的错误消息
root @ ./rdmsr 0x1a0
850089
[root @ ./wrmsr -p 0 0x1a0 0x850289(禁用Core i7中的硬件预取器)
wrmsr:pwrite:输入/输出错误
我在禁用Adjacent cache line prefetcher时收到同样的错误
知道如何解决这个问题吗?提前致谢 .
我读过《Intel 64 and IA-32 Architectures SDM vol 3A, 9.2 MEMORY ORDERING》,但有一个问题一直困扰着我。
如果我首先写入内存地址,然后使用 x2APIC 发送处理器间中断(IPI),这意味着发送 IPI 不需要写入内存(只需使用 wrmsr)。另一个核心接收IPI并读取内存,它会读取正确的值吗?
例如:
最初 x = 0
处理器0:
mov [ _x], 1
wrmsr # use x2APIC to send IPI
Run Code Online (Sandbox Code Playgroud)
处理器1:
# resive IPI, in the interrupt service routine:
mov r1, [ _x]
Run Code Online (Sandbox Code Playgroud)
r1 = 0 允许吗?
我正在尝试在安全启动模式下运行Ubuntu 18.04 /内核4.18.0-16的Intel Skylake计算机上降低CPU的性能,并且需要读取/写入MSR 0x150。我已经签名并加载了msr.ko内核模块,但是甚至不能以root /超级用户身份从msr-tools运行可执行文件rdmsr和wrmsr(我得到权限错误)。我所掌握的是,使用较新的内核(> 3.7?)无法从用户空间访问MSR。描述了一些解决方法:我尝试同时为rdmsr和wrmsr设置“ setcap cap_sys_rawio + ep”,但这没有帮助。我使用的工具iuvolt和UNDERVOLT,而且直接尝试WRMSR。
如何在安全启动模式下执行rdmsr / wrmsr?
我正在尝试使用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 ......我认为就是这样.
在使用GDB调试程序时,有什么方法可以读取特定于x86-64模型的寄存器,尤其是IA32_FS_BASE和IA32_GS_BASE?
使用像Intel的Pintool这样的动态工具包的解决方案是不太可取的,但是同样可以理解。
作为构建过程的一部分,我想运行以下两个命令:
sudo chmod a+r /dev/cpu/*/msr
sudo setcap cap_sys_rawio=ep ./bench
Run Code Online (Sandbox Code Playgroud)
这会将内核模块/dev/cpu/*/msr公开的文件设置msr为世界可读,并设置./bench实际读取这些文件所需的二进制文件(作为构建的一部分生成)的额外权限。
问题是这需要 root 权限,因此sudo.
我想要一个类似于 setuid root 脚本的东西来完成这两个特定的事情,但是在现代 Linux 上不推荐和禁用setuid root 脚本。
对于一个简单的解决方案,我有哪些选择?
仅适用于第二行 (the setcap)的解决方案也很有趣,因为我需要这个来运行每个构建,而chmod每次启动只需要运行一次。
Intel 有时使用MSR_MSR 名称的前缀,有时IA32_甚至对于相同的 MSR 也使用 。
例如,在 SNB 上,在SDM 第 4 卷中,它们记录了IA32_PERF_STATUS和MSR_PERF_STATUS对于 MSR 0x198,其位值有些不同(但不完全不一致1):
那是怎么回事?
1在版本中定义为保留的IA32位在版本中被赋予特定含义MSR。
我正在尝试创建一个内核模块来为x87 FPU启用FOP兼容模式.这是通过设置IA32_MISC_ENABLEMSR中的位2来完成的.这是代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("10110111");
MODULE_DESCRIPTION("Module to enable FOPcode compatibility mode");
MODULE_VERSION("0.1");
static int __init fopCompat_init(void)
{
unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Before trying to set FOP_COMPAT, IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
wrmsrl(MSR_IA32_MISC_ENABLE,misc_enable|MSR_IA32_MISC_ENABLE_X87_COMPAT);
misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Tried to set FOP_COMPAT. Result: IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is now %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
return 0;
}
static void __exit fopCompat_exit(void)
{
const unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Quitting FOP-compat with …Run Code Online (Sandbox Code Playgroud)