在为Windows编写新代码时,我偶然发现_cpuinfo()了Windows API.因为我主要处理Linux环境(GCC),所以我希望能够访问CPUInfo.
我尝试过以下方法:
#include <iostream>
int main()
{
int a, b;
for (a = 0; a < 5; a++)
{
__asm ( "mov %1, %%eax; " // a into eax
"cpuid;"
"mov %%eax, %0;" // eax into b
:"=r"(b) // output
:"r"(a) // input
:"%eax","%ebx","%ecx","%edx" // clobbered register
);
std::cout << "The code " << a << " gives " << b << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这使用组件,但我不想重新发明轮子.有没有其他方法可以在没有汇编的情况下实现CPUInfo?
编译器错误:
lewis@lewis-desktop:~/Desktop/prog$ g++ -Wall CPUInfo.cpp
CPUInfo.cpp: In function ‘int …Run Code Online (Sandbox Code Playgroud) 我知道有这种类似的问题,但在编译不同的文件以不同的标志是不是在这里接受的解决办法,因为这将复杂的代码库真正的快.回答"不,这是不可能的"将会做到.
在任何版本的Clang OR GCC中,是否可以为SSE 2/3/3S/4.1编译内在函数,同时只允许编译器使用SSE指令集进行优化?
编辑:例如,我想编译器转_mm_load_si128()来movdqa,但在任何其他地方比这内在功能,类似于MSVC编译器是如何工作的编译器不可以做发射该指令.
EDIT2:我有动态调度程序和几个版本的单个函数,使用内在函数编写不同的指令集.使用多个文件会使维护更加困难,因为相同版本的代码将跨越多个文件,并且有很多这种类型的函数.
EDIT3:请求的示例源代码:https://github.com/AviSynth/AviSynthPlus/blob/master/avs_core/filters/resample.cpp或该文件夹中的大多数文件.
c ++的方法是在这里(在Windows下).
在同样的答案,但在Linux下使用GCC.
我理解的相关asm代码的摘录:
mov eax, 1
cpuid
mov features, edx
Run Code Online (Sandbox Code Playgroud)
我对BASM不太满意.
我的问题:
我需要按如下方式包装测试
function IsSSE2: Boolean;
begin
try
Result := False;
//
// Some BASM code here
//
except
Result := False;
end;
end;
Run Code Online (Sandbox Code Playgroud)
请帮我.
这是预期的吗?我希望我的Sandy Bridge CPU报告它可以处理MMX,SSE和SSE2指令.这些位是否未设置,因为这些"旧"指令集已被某些较新的指令集"取代"?
#include "CPUID.h"
int main(int argc, char *argv[]) {
CPUID cpuid;
cpuid.load(0);
printf("CPU: %.4s%.4s%.4s",
(const char*)&cpuid.EBX(),
(const char*)&cpuid.EDX(),
(const char*)&cpuid.ECX()
);
char brand[0x30];
cpuid.load(0x80000002); memcpy(brand,&cpuid.EAX(),16);
cpuid.load(0x80000003); memcpy(brand+16,&cpuid.EAX(),16);
cpuid.load(0x80000004); memcpy(brand+32,&cpuid.EAX(),16);
printf("%.48s\n",brand);
cpuid.load(1);
// tests bit 23 of ECX for popcnt instruction support
printf("MMX - %s\n", cpuid.EAX() & (1 << 23) ? "yes" : "no");
printf("SSE - %s\n", cpuid.EAX() & (1 << 25) ? "yes" : "no");
printf("SSE2 - %s\n", cpuid.EAX() & (1 << 26) …Run Code Online (Sandbox Code Playgroud) (这个问题最初是关于CVTSI2SD指令和我认为它在Pentium M CPU上不起作用的事实,但实际上是因为我使用的是自定义操作系统,我需要手动启用SSE.)
我有一个Pentium M CPU和一个自定义操作系统,到目前为止没有使用SSE指令,但我现在需要使用它们.
尝试执行任何SSE指令会导致中断6,非法操作码(在Linux中会导致a SIGILL,但这不是Linux),也在英特尔架构软件开发人员手册中提到(我现在将其称为IASDM) as #UD - 无效操作码(UnDefined Opcode).
编辑:彼得·科德斯实际上确定了正确的原因,并指出了解决方案,我在下面继续:
如果您运行的是不支持在上下文切换时保存XMM regs的古老操作系统,则不会设置其中一个机器控制寄存器中的SSE使能位.
实际上,IASDM提到了这一点:
如果操作系统没有为SSE提供足够的系统级支持,则执行SSE或SSE2指令也可以生成#UD.
Peter Cordes向我指出了SSE OSDev wiki,它描述了如何通过写入CR0和CR4控制寄存器来启用SSE :
clear the CR0.EM bit (bit 2) [ CR0 &= ~(1 << 2) ]
set the CR0.MP bit (bit 1) [ CR0 |= (1 << 1) ]
set the CR4.OSFXSR bit (bit 9) [ CR4 |= (1 << 9) ]
set the CR4.OSXMMEXCPT bit (bit …Run Code Online (Sandbox Code Playgroud) 我可以为Mac OS X创建一个通用二进制文件,它包含我的应用程序的两个版本,一个用SSE4.2编译,另一个用SSE3编译?
在这种情况下,我将使用SSE4.2编译的版本自动加载到支持SSE4.2的CPU.
如果不是,我想获得建议在不支持SSE4.2的旧CPU上运行我的应用程序,但在支持它的CPU上使用SSE4.2.
请注意,如果重要的话,我会定位到Mac AppStore.我使用Clang和Xcode 4.5.
我编译了我的应用程序以使用x86指令集,但我需要以编程方式知道运行可执行文件的机器是否支持amd64指令集.有没有一种简单的方法可以找到它(可能使用CPUID)?
应用程序需要能够在多个操作系统上运行,因此首选非基于操作系统的方法.
1)我想知道我们是否可以编写一个C程序来了解机器的指令集架构.
2)操作系统如何确定计算机在安装过程中运行的指令集架构(ISA)?如果操作系统要支持两个不同的ISA,那么安装文件是否包含两个体系结构的汇编代码?
我想检查运行时是否支持SSE4或AVX,以便我的程序可以利用特定于处理器的指令而无需为每个处理器创建二进制文件.
如果我可以在运行时确定它,我可以使用一个接口并在不同的指令集之间切换.
我有一个图像绘制例程,为 SSE、SSE2、SSE3、SSE4.1、SSE4.2、AVX 和 AVX2 编译多次。我的程序通过检查 CPUID 标志来动态调度这些二进制变体之一。
在 Windows 上,我检查 Windows 版本,如果操作系统不支持 AVX/AVX2 调度,则禁用它们。(例如,仅 Windows 7 SP1 或更高版本支持 AVX/AVX2。)
我想在 Mac OS X 上做同样的事情,但我不确定哪个版本的 OS X 支持 AVX/AVX2。
请注意,我想知道的是与 AVX/AVX2 一起使用的 OS X 的最低版本。不支持 AVX/AVX2 的机器型号。
我在GCC有一个场景给我带来了问题.我得到的行为不是我期望的行为.总结一下这种情况,我提出了一些x86-64的新指令,它们是在硬件模拟器中实现的.为了测试这些指令,我正在使用现有的C源代码并使用十六进制对新指令进行手动编码.因为这些指令与现有的x86-64寄存器交互,所以我使用input/output/clobber列表来声明GCC的依赖关系.
发生的事情是,如果我调用一个函数,例如printf,则不会保存和恢复相关寄存器.
例如
register unsigned long r9 asm ("r9") = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );
Run Code Online (Sandbox Code Playgroud)
101被分配给r9,内联汇编(本例中为假)依赖于r9.这在没有printf的情况下正确运行,但是当它存在时,GCC不会保存和恢复r9,并且在调用自定义指令时会有另一个值.
我想也许GCC可能秘密地将赋值更改为变量 r9,但是当我这样做时
asm volatile (".byte %0" : /* no output */ : "q" (r9) );
Run Code Online (Sandbox Code Playgroud)
看看汇编输出,确实使用的是%r9.
我正在使用gcc 4.4.5.您认为可能会发生什么?我认为GCC将始终在函数调用中保存和恢复寄存器.有什么方法可以强制执行吗?
谢谢!
编辑:顺便说一句,我正在编译这样的程序
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test
Run Code Online (Sandbox Code Playgroud)