I have a small piece of code that I actually use in my simulation, and just compared the performance between C++ and Julia. One function call needs about 7ns with Julia and 1550 ns with C++ and Eigen3.
Why is C++ so slow? Am I doing something wrong?
using StaticArrays, Parameters, BenchmarkTools, LinearAlgebra
@with_kw mutable struct KPS{T}
v_wind_tether::T = zeros(3)
v_apparent::T = zeros(3)
last_tether_drag::T = zeros(3)
end
const kps = KPS{MVector{3, Float64}}()
function calc_drag!(s::KPS, v_segment, unit_vector, rho, v_app_perp, area)
s.v_apparent .= s.v_wind_tether - v_segment
v_app_norm = norm(s.v_apparent)
v_app_perp .= s.v_apparent .- s.v_apparent â‹… unit_vector .* unit_vector
s.last_tether_drag .= -0.5 * rho * norm(v_app_perp) * area .* v_app_perp
v_app_norm
end
@benchmark calc_drag!(kps, v_segment, unit_vector, rho, v_app_perp, area) setup=(
v_segment=MVector(0.0, 0, 0); unit_vector=MVector(0.0,1,0); rho=1.0;
v_app_perp=MVector(10.0,0,0); area=0.3)
And the C++ version:
#include <iostream>
#include <Eigen/Dense>
#include <chrono>
using namespace std;
using Eigen::Vector3d;
using namespace std::chrono;
struct KPS {
Vector3d v_wind_tether;
Vector3d v_apparent;
Vector3d last_tether_drag;
} ;
KPS kps;
double calc_drag(KPS s, Vector3d v_segment, Vector3d unit_vector, double rho, Vector3d v_app_perp, double area)
{
s.v_apparent = s.v_wind_tether - v_segment;
double v_app_norm = s.v_apparent.norm();
v_app_perp = s.v_apparent - s.v_apparent.dot(unit_vector) * unit_vector;
s.last_tether_drag = -0.5 * rho * v_app_perp.norm() * area * v_app_perp;
return v_app_norm;
}
int main()
{
// std::cout << kps.v_wind_tether << std::endl;
Vector3d v_segment(0,0,0); Vector3d unit_vector(0,1,0); double rho = 1.0;
Vector3d v_app_perp(10,0,0); double area = 0.3;
auto start = high_resolution_clock::now();
for(int i=0; i < 1000; i++) {
calc_drag(kps, v_segment, unit_vector, rho, v_app_perp, area);
}
auto stop = high_resolution_clock::now();
cout << "calc_drag needs "
<< ((stop - start).count())/1000
<< " ns." << endl;
}
And the file CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(Tutorial)
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries (${PROJECT_NAME} Eigen3::Eigen)
My problem is, if I tell this on a scientific conference people won’t believe me.