标签: intel

如何阅读英特尔操作码表示法

我正在阅读一些关于英特尔操作码汇编指令的资料,但我无法理解它遵循操作码字节是什么意思.例如:"cw","cd","/ 2","cp","/ 3".请给我一个提示是什么意思或在哪里可以找到完整的参考?提前致谢!

E8 cw CALL rel16相对于下一条指令调用near,relative,displacement

E8 cd CALL rel32相对于下一条指令调用near,relative,displacement

FF / 2 CALL r/m16调用r/m16中给出的接近绝对间接地址

FF / 2 CALL r/m32调用r/m32中给出的接近绝对间接地址

9A cd CALL ptr16:16调用操作数中给出的far,absolute,address

9A cp CALL ptr16:32调用操作数中给出的far,absolute,address

FF / 3 CALL m16:16调用m16:16中给出的远,绝对间接地址

FF / 3 CALL m16:32调用m16:32中给出的远,绝对间接地址

x86 assembly intel machine-code opcode

15
推荐指数
3
解决办法
4909
查看次数

循环展开以实现Ivy Bridge和Haswell的最大吞吐量

我用AVX一次计算八个点产品.在我目前的代码中,我做了类似的事情(在展开之前):

常春藤桥/桑迪桥

__m256 areg0 = _mm256_set1_ps(a[m]);
for(int i=0; i<n; i++) {        
    __m256 breg0 = _mm256_load_ps(&b[8*i]);
    tmp0 = _mm256_add_ps(_mm256_mul_ps(arge0,breg0), tmp0); 
}
Run Code Online (Sandbox Code Playgroud)

Haswell的

__m256 areg0 = _mm256_set1_ps(a[m]);
for(int i=0; i<n; i++) {      
    __m256 breg0 = _mm256_load_ps(&b[8*i]);
    tmp0 = _mm256_fmadd_ps(arge0, breg0, tmp0);
}
Run Code Online (Sandbox Code Playgroud)

我需要多少次为每个案例展开循环以确保最大吞吐量?

对于使用FMA3的Haswell,我认为答案是每个循环的FLOPS用于沙桥和haswell SSE2/AVX/AVX2.我需要将循环展开10次.

对于Ivy Bridge,我认为它是8.这是我的逻辑.AVX添加的延迟为3,延迟乘以5.Ivy Bridge可以使用不同的端口同时进行一次AVX乘法和一次AVX添加.使用符号m进行乘法,a表示加法,x表示无操作,以及表示部分和的数字(例如m5表示乘以第5部分和)我可以写:

port0:  m1  m2  m3  m4  m5  m6  m7  m8  m1  m2  m3  m4  m5  ... 
port1:   x   x   x   x   x  a1  a2  a3  a4  a5  a6  a7  a8  ...
Run Code Online (Sandbox Code Playgroud)

因此,通过在9个时钟周期后使用8个部分和(4个来自负载,5个来自乘法),我可以在每个时钟周期提交一个AVX负载,一个AVX加法和一个AVX乘法.

我想这意味着在Ivy …

c++ x86 sse intel avx

15
推荐指数
2
解决办法
3038
查看次数

VirtualBox - 内核需要一个x86-64 cpu但只检测到一个i686 cpu

Intel i5-2410M CPU运行在2.30 GHz,运行Windows 7 64位操作系统.

我安装了VirtualBox 4.13.

我想跑,ubuntu-14.04-desktop-amd64.iso但我得到一个错误

这个内核需要一个x86-64 cpu,但只检测到一个i686 cpu

我甚至在BIOS设置中启用了Intel Virtualization,然后尝试再次使用该图像,但我仍然得到相同的错误.

还有其他原因导致我无法使用该图像吗?

virtualbox x86-64 intel ubuntu-14.04

15
推荐指数
1
解决办法
6万
查看次数

编译器优化:g ++比intel慢

我最近购买了一台带有双启动的计算机,用C++编写代码.在Windows上我在linux上使用intel C++编译器和g ++.我的程序主要包括计算(具有数值积分的定点迭代算法等).
我以为我可以在我的linux上接近windows的表演,但到目前为止我还没有:对于完全相同的代码,使用g ++编译的程序比使用intel编译器的程序慢约2倍.从我读到的内容来看,icc可以更快,甚至可以达到20-30%的增益,但我没有读到任何关于它的速度提高两倍的东西(而且一般来说我实际上读过两者都应该是等价的).

起初我使用的标志大致相当:

icl/openmp/I"C:\ boost_1_61_0"/ fast program.cpp

g ++ -o program program.cpp -std = c ++ 11 -fopenmp -O3 -ffast-math

根据其他几个主题的建议,我尝试添加/替换其他几个标志,如: - funsafe-math-optimizations,-march = native,-fwhole-program,-Ofast等,只有轻微(或没有)性能增益.

icc真的更快还是我错过了什么? 我对linux很新,所以我不知道,也许我忘了安装正确的东西(比如驱动程序),或者用g ++改变一些选项?我不知道情况是否正常,这就是我更喜欢问的原因.特别是因为我更喜欢使用linux进行理想的编码,所以我宁愿让它达到速度.

编辑:我决定在linux上安装最后一个intel编译器(Intel Compiler C++ 17,update4)来检查.我最终得到了缓解的结果:它并不比gcc做得更好(事实上甚至更糟).我运行交叉比较linux/windows - icc/gcc - 并行或不使用,使用前面提到的标志(进行直接比较),这是我的结果(以ms为单位运行1次迭代的时间):

  1. 普通循环,没有并行化:

    • Windows:
      gcc = 122074; icc = 68799
    • Linux:
      gcc = _91042; icc = 92102
  2. 并行化版本:

    • Windows:
      gcc = 27457; icc = 19800
    • Linux:
      gcc = 27000; icc = 30000

总结一下:这有点乱.在linux上,gcc似乎总是比icc更快,特别是当涉及并行化时(我运行了更长的程序,差异远高于此处的那个).
在Windows上,它是相反的,icc显然支配gcc,特别是当没有并行化时(在这种情况下gcc需要很长时间才能编译).

最快的编译是通过Windows上的并行化和icc完成的.我不明白为什么我不能在linux上复制这个.有什么我需要做的(ubuntu 16.04)来帮助加固我的流程吗?
另一个区别是在Windows上我使用较旧的英特尔作曲家( …

c++ performance g++ intel compiler-optimization

15
推荐指数
2
解决办法
2736
查看次数

为什么此代码链接在英特尔编译器2015而非英特尔编译器2018?

我的团队最近从2015英特尔编译器(并行工作室)升级到2018年版本,我们遇到了一个链接器问题,每个人都在撕扯他们的头发.

我有以下类(为了简洁而适度编辑)来处理子进程的包装和相关的文件描述符以便与它们交谈:

class SubprocWrapper
{
public:
    static const int PASSTHRU_FD = 0;
    static const int MAKE_PIPE = -1;

    typedef std::map<std::string, std::string> EnvMapType;

    static EnvMapType getMyEnv();

    SubprocWrapper(
        int stdin_fd_req,
        int stdout_fd_req,
        int stderr_fd_req,
        const std::string & execPath,
        const std::vector<std::string> & args,
        const std::set<int> & dont_close_fds,
        const EnvMapType * env = 0);
};
Run Code Online (Sandbox Code Playgroud)

然后我用以下代码调用它:

std::string runCmd = "/run/some/file.bin";
std::vector<std::string> args(2);
args[0] = "-c";
args[1] = runCmd;

SubprocWrapper::EnvMapType env_vars = SubprocWrapper::getMyEnv();

SubprocWrapper subproc(
    SubprocWrapper::PASSTHRU_FD,
    SubprocWrapper::PASSTHRU_FD,
    SubprocWrapper::PASSTHRU_FD,
    std::string("/bin/sh"),
    args,
    std::set<int>(), //dont_close_fds = null means …
Run Code Online (Sandbox Code Playgroud)

c++ intel linker-errors

15
推荐指数
1
解决办法
400
查看次数

动态确定恶意AVX-512指令的执行位置

我有一个在支持AVX-512的Intel机器上运行的进程,但是这个进程不直接使用任何AVX-512指令(asm或内在函数)并且编译时-mno-avx512f使编译器不插入任何AVX-512指令.

然而,它在减少的AVX turbo频率下无限运行.毫无疑问,有一个AVX-512指令在某个地方偷偷摸摸,通过一个库,(非常不可能)系统调用或类似的东西.

而不是尝试"二进制搜索"AVX-512指令来自哪里,有没有什么方法可以立即找到它,例如,捕获这样的指令?

操作系统是Ubuntu 16.04.

linux performance x86 intel avx512

15
推荐指数
1
解决办法
648
查看次数

32位Intel处理器上的内存对齐

Intel的32位处理器(如Pentium)具有64位宽的数据总线,因此每次访问可获取8个字节.基于此,我假设这些处理器在地址总线上发出的物理地址总是8的倍数.

首先,这个结论是否正确?

其次,如果它是正确的,那么应该将数据结构成员对齐在8字节边界上.但我见过人们在这些处理器上使用4字节对齐.

他们怎么能这样做呢?

memory x86 32-bit intel alignment

14
推荐指数
2
解决办法
2万
查看次数

为什么不可能将一个字节压入Pentium IA-32上的堆栈?

我已经知道你不能将一个字节直接推到英特尔奔腾的堆栈上,有人能解释一下吗?

我被给出的原因是因为esp寄存器是字可寻址的(或者,这是我们模型中的假设),它必须是"偶数地址".我会假设递减一些32位二进制数的值不会弄乱寄存器的对齐,但显然我不够了解.

我已经尝试了一些NASM测试并提出如果我声明一个变量(咬db 123)并将其推入堆栈,esp减少4(表明它推了32位?).但是,"推送字节咬"(抱歉我选择的变量名称)将导致一种错误:

test.asm:10:错误:不支持的非32位ELF重定位

在这个困难的时期,任何智慧的话都会受到高度赞赏.我是大学一年级学生,对于我在任何一个方面的天真抱歉.

x86 assembly intel

14
推荐指数
2
解决办法
1万
查看次数

为什么genymotion运行如此缓慢?

我正在尝试使用genymotion进行Android开发,因为股票Android模拟器非常缓慢.每个人都在评论它有多快,我似乎无法让它工作.我在bios中启用了虚拟化,我用intel处理器识别实用程序对其进行了双重检查,并确认了这一点.我升级了处理器,这没有帮助.我目前有一个主频为2.66GHz的intel core 2 quad cpu Q9400应该足够快,它应对其他一切都很好,我最近升级到它(它是主板上具有相同插槽的最快的处理器).这里的限制因素是让genymotion启动需要10多分钟?它使用的是intel Q45集成显卡.这是问题吗?我会升级图形,如果是这种情况,我只是想在投入资金并确认genymotion仍然非常慢之前确定.谢谢

android intel genymotion

14
推荐指数
2
解决办法
2万
查看次数

为什么REP LODS AL指令存在?

换句话说,有什么情况我可能需要这个指令吗?

从英特尔说明手册中,这是指令的作用:

从DS加载(E)CX字节:[(E)SI]到AL.

在NASM中采用以下示例:

section .data
    src: db 0, 1, 2, 3

section .code
    mov esi, src
    mov ecx, 4
    rep lodsb    ; mov al, byte[esi + ecx -1]; ecx++  
Run Code Online (Sandbox Code Playgroud)

rep lodsb执行指令时,我无法控制加载的值al.我所能做的只是等待,直到指令终止以获取最后一个值al,当然我可以直接获得,没有循环.

同样的问题也适用于家庭的休息:REP LODS AX,REP LODS EAXREP LODS RAX.

x86 assembly amd intel

14
推荐指数
2
解决办法
803
查看次数