如何自动矢量化基于范围的 for 循环



SO 上发布了一个类似的 g++ 问题,这个问题相当模糊,所以我想我会发布一个 VC++12/VS2013 的具体示例,我们希望得到答案。

交联: G++ , 基于范围和矢量化

MSDN 提供了以下可矢量化的循环示例:

for (int i=0; i<1000; ++i)
{       
    A[i] = A[i] + 1;
}

(http://msdn.microsoft.com/en-us/library/vstudio/jj658585.aspx)

这是我对上述基于范围的类似物的版本,一个 c 风格的怪物,以及使用 std::for_each 的类似循环。我使用 /Qvec-report:2 标志进行编译,并添加了编译器消息作为注释:

#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> vec(1000, 1);
    // simple range-based for loop
    {
        for (int& elem : vec)
        {
            elem = elem + 1;
        }
    } // info C5002 : loop not vectorized due to reason '1304'
    // c-style iteration
    {
        int * begin = vec.data();
        int * end = begin + vec.size();
        for (int* it = begin; it != end; ++it)
        {
            *it = *it + 1;
        }
    } // info C5001: loop vectorized
    // for_each iteration
    {
        std::for_each(vec.begin(), vec.end(), [](int& elem)
        {
            elem = elem + 1;
        });
    } // (no compiler message provided)
    return 0;
}

只有 c 样式循环被矢量化。原因 1304 根据 MSDN 文档如下所示:

1304: 循环包括不同大小的任务。

它提供了以下内容作为触发 1304 消息的代码示例:

void code_1304(int *A, short *B)
{
    // Code 1304 is emitted when the compiler detects
    // different sized statements in the loop body.
    // In this case, there is an 32-bit statement and a
    // 16-bit statement.
    // In cases like this consider splitting the loop into loops to 
    // maximize vector register utilization.
    for (int i=0; i<1000; ++i)
    {
        A[i] = A[i] + 1;
        B[i] = B[i] + 1;
    }
}

我不是专家,但我看不到这种关系。这只是有缺陷的报告吗?我注意到在我的实际程序中,没有一个基于范围的循环被矢量化。什么给?

(如果这是错误的行为,我正在运行VS2013专业版12.0.21005.1 REL)

编辑:错误报告发布:https://connect.microsoft.com/VisualStudio/feedback/details/807826/range-based-for-loops-are-not-vectorized

在这里发布了错误报告:

https://connect.microsoft.com/VisualStudio/feedback/details/807826/range-based-for-loops-are-not-vectorized

响应:

嗨,感谢您的报告。

矢量化基于范围的循环 y 代码是我们积极做的事情 做得更好。我们将解决矢量化问题,以及启用 未来其他C++语言和库功能的自动矢量化 编译器的版本。

发出原因码 1304(在

x64 上)和原因码 1301(在 x86) 是编译器内部的工件。细节,对于 这个特定的代码并不重要。

感谢您的报告!我正在关闭这个MSConnect项目。随意 如果您需要其他任何东西,请回复。

Eric Brumer Microsoft Visual C++ Team

最新更新