Что здесь не так? Приветствуется тестирование с использованием матричной библиотеки.
Спецификация теста:
- 48-ядерный процессор AMD EPYC 7643, четырехканальная ОЗУ 128 ГБ. Но этот вопрос проверяет один поток
- Ubuntu 22.04, g++ 13.3
- Команда установки:
!apt-get install -y -qq libopenblas-dev g++ make
!sudo apt-get update -y
!sudo apt-get install -y libeigen3-dev
!sudo apt-get update
!sudo apt-get install -y libopenblas-dev
!g++ --version
Eigen version: 3.4.0
CBLAS provider: /usr/lib/x86_64-linux-gnu/libopenblas.so.0
OpenBLAS (compile-time): OpenBLAS 0.3.26
OpenBLAS config (runtime): OpenBLAS 0.3.26 NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Zen MAX_THREADS=64
OpenBLAS core (runtime): Zen
Выполнить команду:
rm bench_eigen
g++ -std=c++20 -O3 -march=native -mavx2 -mfma -I /usr/include/eigen3 -DEIGEN_USE_BLAS -DNDEBUG -DEIGEN_DONT_PARALLELIZE bench_eigen.cpp -o bench_eigen -lopenblas -lpthread
OMP_NUM_THREADS=1 \
OPENBLAS_NUM_THREADS=1 \
MKL_NUM_THREADS=1 \
BLIS_NUM_THREADS=1 \
VECLIB_MAXIMUM_THREADS=1 \
NUMEXPR_MAX_THREADS=1 \
TBB_NUM_THREADS=1 \
taskset -c 0 ./bench_eigen
Результат
Testing M = 1
A (naive u32) = 0.00469
E (Eigen u32) = 0.00048
F (Eigen float) = 0.00103
Testing M = 2
A (naive u32) = 0.00032
E (Eigen u32) = 0.00025
F (Eigen float) = 0.00066
Testing M = 4
A (naive u32) = 0.00044
E (Eigen u32) = 0.00035
F (Eigen float) = 0.00486
Testing M = 8
A (naive u32) = 0.0006
E (Eigen u32) = 0.00463
F (Eigen float) = 0.04194
Testing M = 16
A (naive u32) = 0.00135
E (Eigen u32) = 0.00416
F (Eigen float) = 0.00671
Testing M = 32
A (naive u32) = 0.00528
E (Eigen u32) = 0.03033
F (Eigen float) = 0.01717
Testing M = 64
A (naive u32) = 0.05397
E (Eigen u32) = 0.20641
F (Eigen float) = 0.082491
Testing M = 128
A (naive u32) = 0.247691
E (Eigen u32) = 1.63561
F (Eigen float) = 0.481171
Testing M = 256
A (naive u32) = 1.80377
E (Eigen u32) = 13.0081
F (Eigen float) = 1.97049
Testing M = 512
A (naive u32) = 17.8799
E (Eigen u32) = 46.5605
F (Eigen float) = 4.99723
Testing M = 1024
A (naive u32) = 56.7417
E (Eigen u32) = 323.462
F (Eigen float) = 33.8333
Testing M = 2048
A (naive u32) = 487.233
E (Eigen u32) = 2545.22
F (Eigen float) = 234.984
Testing M = 4096
A (naive u32) = 7373.18
E (Eigen u32) = 20315.3
F (Eigen float) = 1574.43
Testing M = 8192
A (naive u32) = 64366.7
E (Eigen u32) = 162164
F (Eigen float) = 11347.4
Testing M = 16384
Код:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using std::cout;
constexpr bool DEBUG = 1;
class MyTimer {
std::chrono::time_point start;
public:
void startCounter() {
if constexpr(DEBUG) start = std::chrono::system_clock::now();
}
int64_t getCounterNs() {
if constexpr(DEBUG) return std::chrono::duration_cast(std::chrono::system_clock::now() - start).count();
else return 0;
}
int64_t getCounterMs() {
if constexpr(DEBUG) return std::chrono::duration_cast(std::chrono::system_clock::now() - start).count();
else return 0;
}
double getCounterMsPrecise() {
if constexpr(DEBUG) return std::chrono::duration_cast(std::chrono::system_clock::now() - start).count()
/ 1000000.0;
else return 0;
}
};
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
using u32 = uint32_t;
using u64 = uint64_t;
constexpr int BLK = 32;
const long long MAXM = 1 u32* {
return static_cast(::operator new[](n * sizeof(u32), std::align_val_t(align)));
};
using f32 = float;
static inline bool feq(f32 x, f32 y, f32 eps = 1e-3f)
{
f32 ax = std::fabs(x), ay = std::fabs(y);
f32 tol = eps * std::max(1.0f, std::max(ax, ay));
return std::fabs(x - y)
Подробнее здесь: https://stackoverflow.com/questions/798 ... iplication
Мобильная версия