我正在阅读一些关于英特尔操作码汇编指令的资料,但我无法理解它遵循操作码字节是什么意思.例如:"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中给出的远,绝对间接地址
我用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 …
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,然后尝试再次使用该图像,但我仍然得到相同的错误.
还有其他原因导致我无法使用该图像吗?
我最近购买了一台带有双启动的计算机,用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次迭代的时间):
普通循环,没有并行化:
并行化版本:
总结一下:这有点乱.在linux上,gcc似乎总是比icc更快,特别是当涉及并行化时(我运行了更长的程序,差异远高于此处的那个).
在Windows上,它是相反的,icc显然支配gcc,特别是当没有并行化时(在这种情况下gcc需要很长时间才能编译).
最快的编译是通过Windows上的并行化和icc完成的.我不明白为什么我不能在linux上复制这个.有什么我需要做的(ubuntu 16.04)来帮助加固我的流程吗?
另一个区别是在Windows上我使用较旧的英特尔作曲家( …
我的团队最近从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) 我有一个在支持AVX-512的Intel机器上运行的进程,但是这个进程不直接使用任何AVX-512指令(asm或内在函数)并且编译时-mno-avx512f使编译器不插入任何AVX-512指令.
然而,它在减少的AVX turbo频率下无限运行.毫无疑问,有一个AVX-512指令在某个地方偷偷摸摸,通过一个库,(非常不可能)系统调用或类似的东西.
而不是尝试"二进制搜索"AVX-512指令来自哪里,有没有什么方法可以立即找到它,例如,捕获这样的指令?
操作系统是Ubuntu 16.04.
Intel的32位处理器(如Pentium)具有64位宽的数据总线,因此每次访问可获取8个字节.基于此,我假设这些处理器在地址总线上发出的物理地址总是8的倍数.
首先,这个结论是否正确?
其次,如果它是正确的,那么应该将数据结构成员对齐在8字节边界上.但我见过人们在这些处理器上使用4字节对齐.
他们怎么能这样做呢?
我已经知道你不能将一个字节直接推到英特尔奔腾的堆栈上,有人能解释一下吗?
我被给出的原因是因为esp寄存器是字可寻址的(或者,这是我们模型中的假设),它必须是"偶数地址".我会假设递减一些32位二进制数的值不会弄乱寄存器的对齐,但显然我不够了解.
我已经尝试了一些NASM测试并提出如果我声明一个变量(咬db 123)并将其推入堆栈,esp减少4(表明它推了32位?).但是,"推送字节咬"(抱歉我选择的变量名称)将导致一种错误:
test.asm:10:错误:不支持的非32位ELF重定位
在这个困难的时期,任何智慧的话都会受到高度赞赏.我是大学一年级学生,对于我在任何一个方面的天真抱歉.
我正在尝试使用genymotion进行Android开发,因为股票Android模拟器非常缓慢.每个人都在评论它有多快,我似乎无法让它工作.我在bios中启用了虚拟化,我用intel处理器识别实用程序对其进行了双重检查,并确认了这一点.我升级了处理器,这没有帮助.我目前有一个主频为2.66GHz的intel core 2 quad cpu Q9400应该足够快,它应对其他一切都很好,我最近升级到它(它是主板上具有相同插槽的最快的处理器).这里的限制因素是让genymotion启动需要10多分钟?它使用的是intel Q45集成显卡.这是问题吗?我会升级图形,如果是这种情况,我只是想在投入资金并确认genymotion仍然非常慢之前确定.谢谢
换句话说,有什么情况我可能需要这个指令吗?
从英特尔说明手册中,这是指令的作用:
从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 EAX和REP LODS RAX.
intel ×10
x86 ×6
assembly ×3
c++ ×3
performance ×2
32-bit ×1
alignment ×1
amd ×1
android ×1
avx ×1
avx512 ×1
g++ ×1
genymotion ×1
linux ×1
machine-code ×1
memory ×1
opcode ×1
sse ×1
ubuntu-14.04 ×1
virtualbox ×1
x86-64 ×1