为了推广 AVX 指令,Intel 提供了一些免费的开发工具:
这里是 Intel 官方的使用说明:http://software.intel.com/en-us/articles/intel-software-development-emulator/
它的使用方式是:
| sde [参数] -- <程序名> |
只是简单的模拟执行,只需:
| sde -- aos_soa_avx.exe |
执行结果如下:

SDE 还附带一个 Intel 的 encode/decode 工具 XED:
|
E:\visual studio work\aos_soa_avx\x64\Release>xed -n 20 -i aos_soa_avx.exe # Intel64 format WARNING: DBGHELP initialization failed. Please copy the appropriate (ia32,intel64) dbghelp.dll to the directory where your xed.exe exists. Version 6.9.3.113 or later is required. # SECTION 0 XDIS 140001000: DATAXFER BASE 48895C2408 mov qword ptr [rsp+0x8], rbx XDIS 140001005: DATAXFER BASE 4889742410 mov qword ptr [rsp+0x10], rsi XDIS 14000100a: DATAXFER BASE 48897C2418 mov qword ptr [rsp+0x18], rdi XDIS 14000100f: PUSH BASE 55 push rbp XDIS 140001010: PUSH BASE 4154 push r12 XDIS 140001012: PUSH BASE 4155 push r13 XDIS 140001014: BINARY BASE 4881EC90060000 sub rsp, 0x690 XDIS 14000101b: MISC BASE 488D6C2440 lea rbp, ptr [rsp+0x40] XDIS 140001020: LOGICAL BASE 4883E5E0 and rbp, 0xffffffffffffffe0 XDIS 140001024: DATAXFER BASE 488B05D51F0000 mov rax, qword ptr [rip+0x1fd5] XDIS 14000102b: LOGICAL BASE 4833C4 xor rax, rsp XDIS 14000102e: DATAXFER BASE 48898540060000 mov qword ptr [rbp+0x640], rax XDIS 140001035: DATAXFER SSE 0F2805D4110000 movaps xmm0, xmmword ptr [rip+0x11d4] XDIS 14000103c: MISC BASE 488D8D40030000 lea rcx, ptr [rbp+0x340] XDIS 140001043: LOGICAL BASE 33D2 xor edx, edx XDIS 140001045: DATAXFER BASE 41B800030000 mov r8d, 0x300 XDIS 14000104b: DATAXFER SSE 0F298520030000 movaps xmmword ptr [rbp+0x320], xmm0 XDIS 140001052: DATAXFER SSE 0F298530030000 movaps xmmword ptr [rbp+0x330], xmm0 XDIS 140001059: CALL BASE E858090000 call 0x1400019b6 XDIS 14000105e: MISC BASE 4C8DA520030000 lea r12, ptr [rbp+0x320] # Errors: 0 #Total decode cycles: 561520 #Total instructions decoded: 20 #Total cycles/instructions decoded: 28076.000000 #Bad times: 0 #Total input length bytes: 101 #Total output length bytes: 0 #Growth bytes: 0 #Shrinkage bytes: 0 #Growth/Shrinkage bytes: -101 #Code size growth percent: -100.000000 |
上面例子反汇编了 aos_soa_avx.exe 的 20 条指令
IACA 的下载和说明在:http://software.intel.com/en-us/articles/intel-architecture-code-analyzer/
为了使 IACA 可以进行分析某一段代码,我们需要在代码中插入两个标记:
|
void foo () ... ... /* 需要分析的代码放这里 */ IACA_END |
宏 IACA_START 和 IACA_END 在 Intel 提供的头文件 <iacaMarks.h> 里定义,在安装 IACA 时附上。
IACA_START 宏是两条指令,定义为:
|
mov ebx, 111 ; bb 6f 00 00 nop ; 64 67 90 |
IACA_END 宏定义为:
|
mov ebx, 222 ; bb de 00 00 nop ; 64 67 90 |
它们标记着要分析的代码的起止点,可以在 c/c++ 代码里插入 inline assembly 方面插入这个标记,如果编译器不支持 inline assembly 行为,只能以手工编辑 Hex 文件的方式,插入这两个 encode 序列。
为了分析 aos_soa_avx_iaca.exe 程序,我们可以使用下面的命令行:
|
E:\visual studio work\aos_soa_avx\x64\Release>iaca -64 -o iaca_out.txt aos_soa_avx_iaca.exe Finished analyzing. Output written to - iaca_out.txt |
结果如下:
|
Intel(R) Architecture Code Analyzer Version - 1.1.3 Analysis Report Port Binding in cycles: N - port number, DV - Divider pipe (on port 0), D - Data fetch pipe (on ports 2 and 3) | Num of | Ports pressure in cycles | | |
从这个结果我们可以得到下面的信息:

以 vmovups ymmword ptr [rbp+r11+0x170] 指令为例, 它的 AGU(地址生成单元)可以被分配到 port 2 或 port 3,实际执行时被分配在 port 3 的 AGU 管道。它的 store 操作被分配到 port 4,花费 2 个 cycle(每个 cycle 执行 128 位的 store),这条指令总共花费 2 cycles,它在译码时被译为 2 个 Uops(微操作码)。
而 add 与 dec 这类通用指令,可以被分配在 port 0,port 1 以及 port 5,这 3 个端口也是 64 位的 ALU 执行端口。
Intel c/c++ 和 visual c/c++ 这两个编译器都提供了 intrinsics 实现,类似于函数库提供,编译器将函数映射到相应的指令。visual studio 2010 sp1 上实现了对 AVX 指令的 intrinsics 库,它是兼容于 Intel 编译器提供的 intrinsics 库。

如上面所示:
这个 intrinsics 函数 _mm256_insertf128_ps() 将直接映射到 vinsertf128 指令,以 c/c++ 层面上,编译器会以函数形式检查它的使用,我们可以如下面这样使用它:
使用这种方式避免了直接在 c/c++ 插入 inline assembly 语句,增加了代码可读性可易用性,
|
__m256 ymm0, ymm1 /* __m256 variable */
ymm0 = _mm256_insertf128_ps(ymm1, xmm0, 1); /* vinsertf128 */
|
值得注意的是:
| 编译器只保证 _mm256_insertf128_ps() 映射到 vinsertf128 指令,并不保证参数和结果映射到哪个 xmm/ymm 寄存器上 |