【发布时间】:2017-06-10 22:19:04
【问题描述】:
我遇到了一个奇怪的现象,无法真正解释。我正在尝试编写一些数字代码,从而对一些实现进行基准测试。我只是想用 SSE 和 AVX 以及 gcc 自动矢量化来对一些矢量添加进行基准测试。为了测试这一点,我使用并修改了下面的代码。
代码:
#include <iostream>
#include <immintrin.h>
#include "../../time/timer.hpp"
void ser(double* a, double* b, double* res, int size){
for(int i(0); i < size; i++ )
{
res[i] = a[i] + b[i];
}
}
void sse(double* a, double* b, double* res, int size){
for (int i(0); i < (size & ~0x1); i += 2 )
{
const __m128d kA2 = _mm_load_pd( &a[i] );
const __m128d kB2 = _mm_load_pd( &b[i] );
const __m128d kRes = _mm_add_pd( kA2, kB2 );
_mm_store_pd( &res[i], kRes );
}
}
void avx(double* a, double* b, double* res, int size){
for (int i(0); i < (size & ~0x3); i += 4 )
{
const __m256d kA4 = _mm256_load_pd( &a[i] );
const __m256d kB4 = _mm256_load_pd( &b[i] );
const __m256d kRes = _mm256_add_pd( kA4, kB4 );
_mm256_store_pd( &res[i], kRes );
}
}
#define N 1e7*64
int main(int argc, char const *argv[])
{
double* a = (double*)_mm_malloc(N*sizeof(double), 64);
double* b = (double*)_mm_malloc(N*sizeof(double), 64);
double* res = (double*)_mm_malloc(N*sizeof(double), 64);
Timer tm;
tm.start();
avx(a,b,res,N);
tm.stop();
std::cout<<"AVX\t"<<tm.elapsed()<<" ms\t"
<<1e-6*N/tm.elapsed() <<" GFLOP/s"<<std::endl;
tm.start();
sse(a,b,res,N);
tm.stop();
std::cout<<"SSE\t"<<tm.elapsed()<<" ms\t"
<<1e-6*N/tm.elapsed() <<" GFLOP/s"<<std::endl;
tm.start();
ser(a,b,res,N);
tm.stop();
std::cout<<"SER\t"<<tm.elapsed()<<" ms\t"
<<1e-6*N/tm.elapsed() <<" GFLOP/s"<<std::endl;
return 0;
}
对于时间和计算的 GFLOP/S,我得到:
./test3
AVX 1892 ms 0.338266 GFLOP/s
SSE 408 ms 1.56863 GFLOP/s
SER 396 ms 1.61616 GFLOP/s
与我的 i5 6600K 大约 170 GFLOP/s 的 peak performance 相比,这显然非常慢。
我在这里遗漏了什么重要的东西吗?我知道在 CPU 上添加向量并不是最好的主意,但这些结果真的很糟糕。感谢您提供任何线索。
【问题讨论】:
-
您犯了一个非常常见(但不明显)的基准测试错误。您忘记从
malloc()初始化内存。所以 AVX 测试(首先运行)实际上是页面错误。 -
一旦你解决了这个问题,你就会遇到这个问题:stackoverflow.com/questions/18159455/…
-
@Mysticial 对!我现在使用热内存进行基准测试,并在每个矢量化上获得大致相同的性能!谢谢。
-
当我进行基准测试时,我通常会在没有计时的情况下进行冷运行。例如。在您的代码中,在计时之前先进行一次迭代
avx(a,b,res,1)。实际上,根据您在做什么,我认为报告冷热时间可能很有用。如果一个函数只被调用一次,那么只报告热时间可能会产生误导。
标签: c++ gcc vectorization sse avx