【问题标题】:libsvm compiled with AVX vs no AVX用 AVX 编译的 libsvm 与没有 AVX
【发布时间】:2019-07-08 10:49:50
【问题描述】:

我编译了一个 libsvm 基准测试应用程序,它使用同一模型在同一图像上执行 svm_predict() 100 次。 libsvm 通过在我的项目中直接包含 svm.cpp 和 svm.h 进行静态编译(MSVC 2017)。

编辑:添加基准细节

for (int i = 0; i < counter; i++)
    {
        std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
        double label = svm_predict(model, input);
        std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();

        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();

        total_time += duration;

        std::cout << "\n\n\n" << sum << " label:" << label << " duration:" << duration << "\n\n\n";
    }

这是我在未对 libsvm 代码进行任何重大修改的情况下进行基准测试的循环。

运行 100 次后,平均运行时间为 4.7 毫秒,无论我是否使用 AVX 指令,都没有区别。为了确保编译器生成正确的指令,我使用英特尔软件开发模拟器检查指令组合

with AVX:
*isa-ext-AVX                                                    36578280
*isa-ext-SSE                                                           4
*isa-ext-SSE2                                                          4
*isa-set-SSE                                                           4
*isa-set-SSE2                                                          4
*scalar-simd                                                    36568174
*sse-scalar                                                            4
*sse-packed                                                            4
*avx-scalar                                                     36568170
*avx128                                                             8363
*avx256                                                             1765

其他部分

without AVX:
*isa-ext-SSE                                                       11781
*isa-ext-SSE2                                                   36574119
*isa-set-SSE                                                       11781
*isa-set-SSE2                                                   36574119
*scalar-simd                                                    36564559
*sse-scalar                                                     36564559
*sse-packed                                                        21341

我希望能得到一些性能改进,我知道 avx128/256/512 的使用并不多,但仍然如此。我有一个 i7-8550U CPU,你认为如果在 skylake i9 X 系列上运行相同的测试,我会看到更大的差异吗?

编辑 我为每个二进制文件添加了指令组合

With AVX:

ADD                                                             16868725
AND                                                                   49
BT                                                                     6
CALL_NEAR                                                       14032515
CDQ                                                                    4
CDQE                                                                3601
CMOVLE                                                                 6
CMOVNZ                                                                 2
CMOVO                                                                 12
CMOVZ                                                                  6
CMP                                                             25417120
CMPXCHG_LOCK                                                           1
CPUID                                                                  3
CQO                                                                   12
DEC                                                                   68
DIV                                                                    1
IDIV                                                                  12
IMUL                                                                3621
INC                                                              8496372
JB                                                                   325
JBE                                                                    5
JL                                                                  7101
JLE                                                                38338
JMP                                                              8416984
JNB                                                                    6
JNBE                                                                   3
JNL                                                                  806
JNLE                                                                  61
JNS                                                                    1
JNZ                                                             22568320
JS                                                                     2
JZ                                                               8465164
LEA                                                             16829868
MOV                                                             42209230
MOVSD_XMM                                                              4
MOVSXD                                                              1141
MOVUPS                                                                 4
MOVZX                                                               3684
MUL                                                                   12
NEG                                                                   72
NOP                                                                 4219
NOT                                                                    1
OR                                                                    14
POP                                                                 1869
PUSH                                                                1870
REP_STOSD                                                              6
RET_NEAR                                                            1758
ROL                                                                    5
ROR                                                                   10
SAR                                                                    8
SBB                                                                    5
SETNZ                                                                  4
SETZ                                                                  26
SHL                                                                 1626
SHR                                                                  519
SUB                                                                 6530
TEST                                                             5616533
VADDPD                                                               594
VADDSD                                                           8445597
VCOMISD                                                                3
VCVTSI2SD                                                           3603
VEXTRACTF128                                                           6
VFMADD132SD                                                           12
VFMADD231SD                                                            6
VHADDPD                                                                6
VMOVAPD                                                               12
VMOVAPS                                                             2375
VMOVDQU                                                                1
VMOVSD                                                          11256384
VMOVUPD                                                              582
VMULPD                                                               582
VMULSD                                                           8451540
VPXOR                                                                  1
VSUBSD                                                           8407425
VUCOMISD                                                            3600
VXORPD                                                              2362
VXORPS                                                              3603
VZEROUPPER                                                             4
XCHG                                                                   8
XGETBV                                                                 1
XOR                                                              8414763
*total                                                         213991340

第二部分

No AVX:
ADD                                                             16869910
ADDPD                                                               1176
ADDSD                                                            8445609
AND                                                                   49
BT                                                                     6
CALL_NEAR                                                       14032515
CDQ                                                                    4
CDQE                                                                3601
CMOVLE                                                                 6
CMOVNZ                                                                 2
CMOVO                                                                 12
CMOVZ                                                                  6
CMP                                                             25417408
CMPXCHG_LOCK                                                           1
COMISD                                                                 3
CPUID                                                                  3
CQO                                                                   12
CVTDQ2PD                                                            3603
DEC                                                                   68
DIV                                                                    1
IDIV                                                                  12
IMUL                                                                3621
INC                                                              8496369
JB                                                                   325
JBE                                                                    5
JL                                                                  7392
JLE                                                                38338
JMP                                                              8416984
JNB                                                                    6
JNBE                                                                   3
JNL                                                                  803
JNLE                                                                  61
JNS                                                                    1
JNZ                                                             22568317
JS                                                                     2
JZ                                                               8465164
LEA                                                             16829548
MOV                                                             42209235
MOVAPS                                                              7073
MOVD                                                                3603
MOVDQU                                                                 2
MOVSD_XMM                                                       11256376
MOVSXD                                                              1141
MOVUPS                                                              2344
MOVZX                                                               3684
MUL                                                                   12
MULPD                                                               1170
MULSD                                                            8451546
NEG                                                                   72
NOP                                                                 4159
NOT                                                                    1
OR                                                                    14
POP                                                                 1865
PUSH                                                                1866
REP_STOSD                                                              6
RET_NEAR                                                            1758
ROL                                                                    5
ROR                                                                   10
SAR                                                                    8
SBB                                                                    5
SETNZ                                                                  4
SETZ                                                                  26
SHL                                                                 1626
SHR                                                                  516
SUB                                                                 6515
SUBSD                                                            8407425
TEST                                                             5616533
UCOMISD                                                             3600
UNPCKHPD                                                               6
XCHG                                                                   8
XGETBV                                                                 1
XOR                                                              8414745
XORPS                                                               2364
*total                                                         214000270

【问题讨论】:

  • 你所说的MVS是指MSVC吗?请注意,非 AVX 版本中的 SSE2 指令数与 AVX 版本中的 AVX 指令数相同。 scalar-simd 在这两种情况下也大致相同。我不确定这些指令类是否相互排斥,但我认为它们可以相互包容。这意味着无论您是否启用 AVX,这些 SIMD 指令中的大多数实际上都在标量模式下使用。
  • @HadiBrais 标量模式是什么意思?你能详细说明一下吗?是的,我的意思是 MSVC
  • 您是否查看了库的反汇编并看到了大量的向量指令,例如(v)addps(v)mulps 等?相反,如果您主要有 addssmulss 指令,则该代码未矢量化。
  • 但是你说你在你的项目中包含了svm.cpp,所以它也被编译了。是的,某些东西的自动矢量化显然是有效的,但可能只是一个初始化循环。无论哪种方式,它都只有几千条指令与 36M 标量指令。所以很明显,这完全取决于您使用的 SVM 库函数。看来这个并没有有意义地使用 SIMD。 (哦,我把 SVM 和 SVML 混淆了(Intel's Short Vector Math Library, stuff like _mm_sin_ps(),它不是开源的。)
  • 查看 chtz 的回答。 x86 使用 SSE1/2 或 AVX 进行标量 FP 数学,仅使用 XMM 向量寄存器的低元素。它比 x87 好一些(更多的寄存器和扁平的寄存器集),但它仍然是每条指令只有一个结果。

标签: performance visual-c++ x86 compiler-optimization libsvm


【解决方案1】:

您列出的几乎所有算术指令都适用于标量,例如,(V)SUBSD 表示 SUBstract Scalar Double。前面的V 本质上只是意味着使用了 AVX 编码(这也清除了寄存器的上半部分,而 SSE 指令不这样做)。但是根据您列出的说明,运行时应该几乎没有任何差异。

现代 x86 使用 SSE1/2 或 AVX 进行标量 FP 数学运算,仅使用 XMM 向量寄存器的低元素。它比 x87 稍微好一点(更多的寄存器和扁平的寄存器集),但它仍然是每条指令只有一个结果。

有几千条压缩 SIMD 指令,而标量指令约为 3600 万条,因此只有相对不重要的部分代码被自动向量化,并且可以从 256 位向量中受益。

【讨论】:

  • 是的,MSVC 知道使用 VZEROUPPER 来避免像 Why is this SSE code 6 times slower without VZEROUPPER on Skylake? 这样的错误依赖的惩罚。可能如果您使用 AVX 内在函数而不使用 -arch:AVX 进行编译,您可以欺骗它不这样做,至少对于旧版本的编译器,我想我记得在没有 -arch:AVX 的情况下让它发出混合的 SSE/AVX 代码。但希望它能阻止你在脚上开枪。 (除非您告诉它针对 KNL Xeon Phi 进行调整,其中 vzeroupper 很慢而且没有帮助。)
  • @HadiBrais:我不相信 OP 的每条指令编号。其中一个的总指令比另一个多得多,所以它可能需要更多的迭代。例如126M cmp 与 25M。所以可能是循环迭代的 5 倍,与标量指令的 5 倍差异相匹配。但是,有一些差异,例如 JZ 与 JNZ 的比率。使用 AVX 的比率为 2.6,而仅使用 SSE 的比率为 2.1。
  • @chtz 我的理解是所有的列表都显示了动态指令的数量。只是前两个列表将所有指令分类为可能重叠的类。
  • @chtz 这取决于处理器。无论如何,根本不清楚他们为什么会有相同的表现。我怀疑他们有不同的瓶颈。如果不彻底检查代码中的热循环,就很难判断。
  • @HadiBrais 看来您对总指令数的看法是正确的,我针对不同数量的循环运行它。我更新了指令计数器,现在它们看起来更好了。还包括指令总数。谢谢
猜你喜欢
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2017-05-08
相关资源
最近更新 更多