我需要arm和x86之间的跨平台SIMD指令。所以我找到了一个名为libsimdpp的库并运行了这个示例。
我稍微更改了一下,以将其与添加两个数组的标准cpp方法进行比较,但是libSimd示例的性能总是更差。
后果
是我使用图书馆的方式有问题,还是它的建造方式有问题。
我对示例所做的更改。
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;
}
即使您直接使用_mm_add_ps
intrinsic,调试构建减慢手动矢量化代码的速度也比减慢标量的速度慢,这是正常的。(通常是因为您倾向于使用更多单独的语句,而调试代码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方法,它应该是升序或降序,我需要两者。我想知道