当前位置: 首页 > 知识库问答 >
问题:

libsimdpp 较慢,然后调试 gcc

袁弘化
2023-03-14

我需要arm和x86之间的跨平台SIMD指令。所以我找到了一个名为libsimdpp的库并运行了这个示例。

我稍微更改了一下,以将其与添加两个数组的标准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个答案

公羊俭
2023-03-14

即使您直接使用_mm_add_psintrinsic,调试构建减慢手动矢量化代码的速度也比减慢标量的速度慢,这是正常的。(通常是因为您倾向于使用更多单独的语句,而调试代码gen会分别编译每个语句。)

您正在使用一个C包装器库,所以在调试模式下,这是一个重要的额外层,因为您告诉编译器不要这样做,所以不会优化掉。所以这并不奇怪,它会减慢很多,以至于比标量更糟糕。请参阅为什么这个C包装器类没有被内联?例如。(即使__attribute__((always_inline))对性能也没有太大帮助;传递args仍然会导致重新加载/存储以制作另一个副本)。

不要对调试版本进行基准测试,它毫无用处,并且很少告诉您有关-O3性能的信息。(您可能还想使用-O3-mar=native-ffast-ath,具体取决于您的用例。)

 类似资料:
  • 当我调试我的解决方案时,vs 2017非常滞后和缓慢,就像它必须在后台操作一些沉重的东西。 null

  • 问题内容: 我正在尝试使用Java8按名称对员工进行排序,然后按年龄进行排序,我在下面创建了该代码,但它给了我一个编译器错误 但是如果我明确指定类型,它就可以工作 或通过创建两个s和链 我已经在左侧指定了类型,但是为什么自动类型推断没有找到正确的类型并期望明确指定。 有人可以澄清吗? 这是代码 输出 问题答案: Java需要知道所有变量的类型。在许多lambda中,它可以推断类型,但是在您的第一个

  • 问题内容: 明天我要进行考试,但我听不懂书中的解释,感谢您的帮助: 输出: 为什么这会打印两个大小相同的负数而不是正负数? 问题答案: 由于无声整数溢出:is 和is ,因此is ,即is ,根据定义,它对于整数而言太大。因此它溢出并变成… 您还可以检查: 打印相同的东西。 从技术上讲,结果由Java语言规范#15.18.2定义: 如果整数加法溢出,则结果是数学和的低阶位,以某种足够大的二进制补码

  • 问题内容: 我需要查询一个表并选择4列的值中的3个。我需要比较第三列和第四列的值,然后选择较大的值。 例如: 我需要退货: 我一直在尝试使用IF / ELSE,但是我似乎无法正确使用语法 问题答案: 在T-SQL中, IF 命令用于程序控制。例如: 在SQL语句中,您需要 CASE 。

  • 我是Java新手,我正在尝试使用Lambda表达式和比较器。我有一个具有其他getter和toString方法的公共类人员: 现在我想对一个Person[]列表进行排序,首先按String(降序)进行比较,然后按年龄(升序)进行比较,然后按计算机数量(降序)进行比较,最后按Salary(升序)进行比较。我无法实现可比较,因为如果我重写compareTo方法,它应该是升序或降序,我需要两者。我想知道