libsimdpp较慢然后调试gcc

时间:2019-03-01 16:31:05

标签: c++ simd

我需要arm和x86之间的跨平台SIMD指令。因此,我找到了一个名为libsimdpp的库,并运行了这个example

我做了一些更改,以将其与添加两个数组的标准cpp方法进行比较,但libSimd示例的效果总是较差。

结果

  • 23毫秒-libSimd
  • 1毫秒-正常cpp加法

我使用库的方式或构建方式有问题吗?

我对示例所做的更改。

https://pastebin.com/L14DCrky

#define SIMDPP_ARCH_X86_SSE4_1 true
#include <simdpp/simd.h>
#include <iostream>
#include <chrono>
//example where i got this from
//https://github.com/p12tic/libsimdpp/tree/2e5c0464a8069310d7eb3048e1afa0e96e08f344

// Initializes vector to store values
void init_vector(float* a, float* b, size_t size) {
    for (int i=0; i<size; i++) {
        a[i] = i * 1.0;
        b[i] = (size * 1.0) - i - 1;
    }
}



using namespace simdpp;
int main() {
    //1048576
    const unsigned long SIZE = 4 * 150000;

    float vec_a[SIZE];
    float vec_b[SIZE];
    float result[SIZE];

    ///////////////////////////*/
    //LibSIMDpp
    //*
    auto t1 = std::chrono::high_resolution_clock::now();

    init_vector(vec_a, vec_b, SIZE);
    for (int i=0; i<SIZE; i+=4) {
        float32<4> xmmA = load(vec_a + i);  //loads 4 floats into xmmA
        float32<4> xmmB = load(vec_b + i);  //loads 4 floats into xmmB
        float32<4> xmmC = add(xmmA, xmmB);  //Vector add of xmmA and xmmB
        store(result + i, xmmC);            //Store result into the vector
    }

    auto t2 = std::chrono::high_resolution_clock::now();

    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count()
              << " milliseconds\n";
    //*/


    ///////////////////////////*/
    //standard
    //*
    init_vector(vec_a, vec_b, SIZE);
    t1 = std::chrono::high_resolution_clock::now();

    for (auto i = 0; i < SIZE; i++) {
        result[i] = vec_a[i]  + vec_b[i];
    }

    t2 = std::chrono::high_resolution_clock::now();

    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count()
              << " milliseconds\n";
    //*/


    int i = 0;
    return 0;
}

1 个答案:

答案 0 :(得分:1)

即使直接使用_mm_add_ps内部函数,调试构建也会减慢手动矢量化代码的速度,而不是减慢标量的速度。 (通常是因为您倾向于使用更多单独的语句,并且调试代码生成器分别编译每个语句。)

您正在使用C ++包装器库,因此在调试模式下,这是重要的额外一层,不会会优化,因为您告诉编译器不要这样做。因此毫不奇怪地将其减慢得比标量更糟。  例如,请参见Why is this C++ wrapper class not being inlined away?。 (即使__attribute__((always_inline))也不会对性能有很大帮助;传递args仍会导致重新加载/存储以制作另一个副本)。

没有基准调试版本,它没有用,并且告诉您非常 -O3性能。(根据您的使用情况,您可能还想使用-O3 -march=native -ffast-math。)