为啥 MSVC12 的自动矢量化器不分析函数模板?

Posted

技术标签:

【中文标题】为啥 MSVC12 的自动矢量化器不分析函数模板?【英文标题】:Why would function templates not be analyzed by MSVC12's auto-vectorizer?为什么 MSVC12 的自动矢量化器不分析函数模板? 【发布时间】:2018-08-24 00:16:31 【问题描述】:

VS2013 中的自动矢量化或自动并行器 (/Qpar) 引擎看不到函数模板。

例如这段代码:

void foo::someFunc(int a)

    int myArray[1000000];

    for (unsigned i = 0; i < 1000000; i++)
    
       myArray[i] = i+1;
    

似乎已被识别,我从 /Qvec-report:2 和 /Qpar-report:2: 获得了适当的输出:

foo.cpp

--- Analyzing function: void __cdecl foo::someFunc(int) __ptr64
c:\visual studio 2013\projects\autovectest\autovectest\foo.cpp(18) : info C5001: loop vectorized
c:\visual studio 2013\projects\autovectest\autovectest\foo.cpp(18) : info C5012: loop not parallelized due to reason '1007'
AutoVecTest.vcxproj -> c:\visual studio 2013\Projects\AutoVecTest\x64\Debug\AutoVecTest.dll

但是,只要我把someFunc() 变成一个函数模板:

template <class T>
void foo::someFunc(T a)

    int myArray[1000000];

    for (unsigned i = 0; i < 1000000; i++)
    
        myArray[i] = i+1;
    

我没有从日志中的自动矢量化器或自动并行化器获得任何信息:

foo.cpp
AutoVecTest.vcxproj -> c:\visual studio 2013\Projects\AutoVecTest\x64\Debug\AutoVecTest.dll

我没有使用 Why would /Qvec-report:2 return nothing ? (MSVC 2012) 中所述的 /GL

【问题讨论】:

你真的在调用这个函数吗? 1&gt;--- Analyzing function: void __cdecl someFunc&lt;int&gt;(int) 1&gt;c:\temp\test\test.cpp(321) : info C5001: loop vectorized 1&gt;c:\temp\test\test.cpp(321) : info C5012: loop not parallelized due to reason '1007' 我想我不在我的示例代码中。但我与我的现实生活中的代码。让我调整我的示例代码并报告回来 使用我的示例代码成功!如果我调用模板化函数(即int a; someFunc(a); 或显式实例化函数(template void someFunc(int a)),我会收到自动矢量化器/并行化器消息。 查看反汇编,我猜我的示例代码并不能准确反映我的实际代码问题。在我的示例代码中,如果我不调用 someFunc() 或显式实例化 someFunc(),则 someFunc() 不会出现在 obj 文件中(使用 dumpbin /disasm)。但是,在我的实际代码中,我的函数出现在 obj 文件中,因此至少正在创建模板函数。所以我不确定这是问题所在...... 好的,我发现了示例代码和我的真实代码之间的差异。我的真实代码的头文件有一个从未关闭过的#pragma optimize("gt", on),因此它错误地自动矢量化了一些不应该的功能。一旦我在预期的功能之后添加了#pragma optimize("", on),自动矢量化器的行为就如其所愿。 【参考方案1】:

    正如 Retired Ninja 指出的那样,确保您的函数模板被实际调用或实例化。

    确保启用了正确的优化编译标志。 YMMV 在这里,但Visual Studio 2012's Auto-Vectorization Cookbook 说/O2/O2 /GL 会起作用。另一个用户发现 /GL 对他们不起作用 (Why would /Qvec-report:2 return nothing ? (MSVC 2012))。使用#pragma("gt", on) 为我启用了自动矢量化器。

【讨论】:

以上是关于为啥 MSVC12 的自动矢量化器不分析函数模板?的主要内容,如果未能解决你的问题,请参考以下文章

MSVC:为啥包含基本 QString 操作的函数没有内联?

MSVC:显式模板实例化失败,而隐式实例化成功

ARCGIS矢量数据批量合库为啥会失败

为啥 Pandas 应用可以比矢量化内置函数更快 [重复]

MSVC:隐式模板实例化,但未使用模板构造函数

为啥在 __assume 中使用函数调用时 MSVC 不报错?