CMake:为Eigen库使能向量化

news2024/12/27 10:23:39

CMake:为Eigen库使能向量化

  • 导言
  • 构建Eigen
  • 项目结构
  • CMakeLists.txt
  • 相关源码

导言

本篇开始将涉及检测外部库相关的内容,期间会穿插着一些其他的内容。为了能够使得系统在系统中运行Eigen库,我们首先需要在系统中配置好Eigen库。然后介绍与Eigen库相关的CMake配置。

构建Eigen

Windows

  • 从官网下载安装包(下载ZIP格式):

https://eigen.tuxfamily.org/index.php?title=Main_Page
在这里插入图片描述

  • 解压到某一路径中,使用cmake编译。这里以vs15以及x64为例:
    在这里插入图片描述
    在这里插入图片描述
  • 选择输出路径并点击generate:
    在这里插入图片描述
  • VS打开项目
    在这里插入图片描述
  • 在vs2015中生成INSTALL。右键点击“生成”:
    在这里插入图片描述
  • 将生成后的库添加到环境变量中:
    在这里插入图片描述

ubuntu

  • 从官网下载安装包(下载tar.gz格式):

https://eigen.tuxfamily.org/index.php?title=Main_Page
在这里插入图片描述

  • Eigen包安装
    下载完成后,对压缩包进行解压后(解压在home目录即可),运行如下命令进行安装:
cd (eigen文件夹中)
mkdir build
cd build
cmake ..
sudo make install
  • 将eigen文件复制到本地调用文件夹中(/usr/include)
sudo cp -r /usr/local/include/eigen3 /usr/include 

项目结构

.
├── CMakeLists.txt
└── linear_algebra.cpp

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter2/05

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(eigen_tensor LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Eigen3 3.4 REQUIRED CONFIG)

include(CheckCXXCompilerFlag)

check_cxx_compiler_flag("-march=native" _march_native_works)
check_cxx_compiler_flag("-xHost" _xhost_works)

set(_CXX_FLAGS)
if(_march_native_works)
    message(STATUS "Using processor's vector instructions (-march=native compiler flag set)")
    set(_CXX_FLAGS "-march=native")
elseif(_xhost_works)
    message(STATUS "Using processor's vector instructions (-xHost compiler flag set)")
    set(_CXX_FLAGS "-xHost")
else()
    message(STATUS "No suitable compiler flag found for vectorization")
endif()

add_executable(linear-algebra-unoptimized linear_algebra.cpp)
target_link_libraries(linear-algebra-unoptimized
  PRIVATE Eigen3::Eigen
)

add_executable(linear-algebra linear_algebra.cpp)
target_compile_options(linear-algebra
  PRIVATE ${_CXX_FLAGS}
)
target_link_libraries(linear-algebra
  PRIVATE Eigen3::Eigen
)
find_package(Eigen3 3.4 REQUIRED CONFIG)

find_packageCMake中的一个命令,用于查找和加载特定的第三方库(例如Eigen3)的CMake配置文件。

Eigen3 是一个用于线性代数计算的C++模板库,它提供了矩阵、向量、矢量计算等功能。通过在CMake中使用 find_package(Eigen3 3.4 REQUIRED CONFIG) 命令,告诉CMake去查找Eigen3库,并且要求它的版本至少是3.4REQUIRED 参数表示如果找不到Eigen3库,CMake将会报错并停止构建。

CONFIG 参数指示CMake查找Eigen3CMake配置文件(通常是 Eigen3Config.cmake 或类似名称),其中包含有关库的信息和设置。

一旦找到Eigen3库的CMake配置文件,CMake会加载该配置文件并设置相关的变量,例如 EIGEN3_INCLUDE_DIR,其中包含了Eigen3库的头文件路径。在接下来的CMake构建中,你可以使用这些设置的变量来链接和包含Eigen3库。

include(CheckCXXCompilerFlag)

CMake中,include(CheckCXXCompilerFlag) 是一个用于检查C++编译器标志是否可用的CMake命令。

这个命令的作用是为了检查特定的C++编译器标志是否受支持。在某些情况下,需要根据编译器的不同来启用或禁用一些特性或优化选项。

使用这个命令的一般形式是:

include(CheckCXXCompilerFlag <flag>)

其中<flag>是你要检查的C++编译器标志,例如 -std=c++11-fPIC 等。

此命令将尝试将指定的编译器标志添加到C++源代码,并编译一个简单的测试程序来检查编译器是否支持该标志。如果支持,那么CMake将定义一个CMake变量,例如 CMAKE_REQUIRED_FLAGSCMAKE_REQUIRED_LIBRARIES,来表示该标志是可用的。

通过这种方式,可以在CMake脚本中根据编译器支持情况进行条件编译或设置不同的选项。

例如,假设我们要检查编译器是否支持C++11标准:

include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11)
if (COMPILER_SUPPORTS_CXX11)
    # 设置C++11标准
    set(CMAKE_CXX_STANDARD 11)
    message(STATUS "C++11 supported by the compiler.")
else ()
    message(FATAL_ERROR "C++11 is not supported by the compiler.")
endif ()
check_cxx_compiler_flag("-march=native" _march_native_works)
check_cxx_compiler_flag("-xHost" _xhost_works)

set(_CXX_FLAGS)
if(_march_native_works)
    message(STATUS "Using processor's vector instructions (-march=native compiler flag set)")
    set(_CXX_FLAGS "-march=native")
elseif(_xhost_works)
    message(STATUS "Using processor's vector instructions (-xHost compiler flag set)")
    set(_CXX_FLAGS "-xHost")
else()
    message(STATUS "No suitable compiler flag found for vectorization")
endif()

这段CMake代码片段用于检查编译器是否支持特定的矢量指令优化标志,并根据结果设置 _CXX_FLAGS 变量以启用适当的矢量化优化。

-march=native 是一个编译器标志,用于告诉编译器根据当前主机的处理器架构来优化生成的机器码。这个标志会让编译器针对当前的 CPU 架构生成最优化的代码,以充分利用处理器的特性和指令集。

例如,在使用 -march=native 标志编译代码时,如果你的计算机的处理器支持 AVX2 指令集,编译器将会针对 AVX2 进行优化。如果运行这个优化过的代码在支持 AVX2 的处理器上,它将能够获得更高的性能。

请注意,使用 -march=native 标志编译代码可能会导致生成的可执行文件在其他不同架构的计算机上运行不正确或不稳定。因此,在分发或共享可执行文件时,最好使用更加通用的编译选项,除非确实需要充分利用特定处理器架构的优化。

-xHostIntel 编译器的编译选项,用于指示编译器使用主机处理器支持的最高级别的指令集来优化生成的机器码。

类似于 -march=native-xHost 也会让编译器根据当前主机的处理器架构来选择最优化的指令集。它会自动根据当前系统的处理器类型来决定使用最高级别的指令集,以充分利用处理器的性能和功能。

然而,与 -march=native 不同的是,-xHost 是特定于 Intel 编译器的选项,而不是在其他编译器中通用的标志。

请注意,与 -march=native 一样,使用 -xHost 也可能会导致生成的可执行文件在其他不同架构的计算机上运行不正确或不稳定,因此在分发或共享可执行文件时需谨慎使用。

相关源码

linear_algebra.cpp

#include <eigen3/Eigen/Dense>
#include <chrono>
#include <iostream>
EIGEN_DONT_INLINE

double simple_function(Eigen::VectorXd &va, Eigen::VectorXd &vb) {
  // this simple function computes the dot product of two vectors
  // of course it could be expressed more compactly
  double d = va.dot(vb);
  return d;
}

int main() {
  int len = 1000000;
  int num_repetitions = 100;
  // generate two random vectors
  Eigen::VectorXd va = Eigen::VectorXd::Random(len);
  Eigen::VectorXd vb = Eigen::VectorXd::Random(len);
  
  double result;
  auto start = std::chrono::system_clock::now();
  for (auto i = 0; i < num_repetitions; i++) {
    result = simple_function(va, vb);
  }
  auto end = std::chrono::system_clock::now();
  auto elapsed_seconds = end - start;
  std::cout << "result: " << result << std::endl;
  std::cout << "elapsed seconds: " << elapsed_seconds.count() << std::endl;
}

输出结果

./linear-algebra-unoptimized
result: -261.505
elapsed seconds: 1.97964

./linear-algebra
result: -261.505
elapsed seconds: 1.05048

最后:保持好的心态!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/820966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PostMan调用gitlab接口,OAuth 2.0 身份认证 API ,copy完事~

获取token接口&#xff1a; https://gitlab.***.com/oauth/token &#xff0c;接下来就可以调用其他功能的接口了 例&#xff1a;创建账户&#xff0c;将获取到的access_token放置在接口请求的token中 其他接口调用同上

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

【图解】反卷积Deconvolution

1. 反池化和反卷积 以下是DeconvNet的整体架构&#xff1a; unpooling&#xff1a; (Unpooling操作需要依据max pooling记录的位置,将每个pooling区域还原回去。在进行max pooling时,我们记录下每个pooling区域的最大激活值所在的位置坐标,在unpooling时就可以依据这些坐标,把激…

express学习笔记4 - 热更新以及express-boom

我们每次改动代码的时候都要重启项目&#xff0c;现在我们给项目添加一个热更新 npm install --save-dev nodemon # or using yarn: yarn add nodemon -D 在package.json添加一行代码 "dev": "nodemon ./bin/www" 重启项目 然后随便做改动&#xff…

将子域名连接到 Shopify 的步骤,也就是把不是www的域名链接到shopify商店,二级域名链接到shopify店铺

将子域名连接到 Shopify 的步骤&#xff1a; 1. Shopify 后台&#xff1a; 首先&#xff0c;检查您的 Shopify 控制面板并验证您使用的是 Shopify 提供的免费域&#xff08;也就是xxxxxxxxx.myshopify.com&#xff09;。这是至关重要的&#xff0c;因为它将帮助您在连接子域时避…

数据结构--图的遍历 DFS

数据结构–图的遍历 DFS 树的深度优先遍历 //树的先根遍历 void PreOrder(TreeNode *R) {if(R ! NULL){visit(R); //访问根节点while(R还有下一个子树T)PreOrder(T);//先根遍历下一棵子树} }图的深度优先遍历 bool visited [MAX_VERTEX_NUM]; //访问标记数组 void DFS(Grap…

最长公共前缀_力扣14

文章目录 题目描述法一 横向比较 题目描述 法一 横向比较 将多个字符串比较转换为两两比较&#xff0c;如果比较完最长公共前缀已经是空串&#xff0c;则最长公共前缀一定是空串&#xff0c;因此不需要继续遍历剩下的字符串&#xff0c;直接返回空串。 string longestCommonPre…

Django实现音乐网站 ⑵

使用Python Django框架制作一个音乐网站&#xff0c;在系列文章1的基础上继续开发&#xff0c;本篇主要是后台歌手表模块开发。 目录 表结构设计 歌手表&#xff08;singer&#xff09;结构 创建表模型 设置图片上传路径 创建上传文件目录 生成表迁移 执行创建表 后台管…

uniapp 路由跳转方式

export function goBack(index, url) {if (index 1) { // 关闭当前页&#xff0c;返回上一页面或多级页面。uni.navigateBack({delta: url,animationType: pop-out,animationDuration: 300});} else if (index 2) { // 保留当前页&#xff0c;跳转到非tabbar页面&#xff0c;…

GWJDN-1000B高温介电温谱分析仪

GWJDN-1000B高温介电温谱分析仪 关键词&#xff1a;弹性常数等C-V ,介电常数&#xff0c;损耗角&#xff0c;电导率&#xff0c;C-特性 产品简介 GWJDN-1000B高温介电温谱分析仪采用当前的自动平衡电桥原理研制成功的新一高温介电温谱分析仪&#xff0c;产品全新的电子器件。…

【TypeScript】类型断言的基本使用

类型断言的概念 有些时候开发者比TS本身更清楚当前的类型是什么&#xff0c;可以使用断言&#xff08;as&#xff09;让类型更加精确和具体。 类型断言&#xff08;Type Assertion&#xff09;表示可以用来手动指定一个值的类型。 类型断言语法&#xff1a; 值 as 类型 或 <…

Character.AI搭建了用户创建AI角色并与之聊天的平台及社区

character Character.AI 公司是一家致力于通用人工智能&#xff08;AGI&#xff09;的全栈公司&#xff0c;于2021年10月创立&#xff0c;创始团队来自Google Brain和Meta AI&#xff0c;是深度学习、大型语言模型和对话领域的专家。Character.AI搭建了用户创建AI角色并与之聊…

Patchwork 黑客组织瞄准我国大学和研究机构

据知道创宇404高级威胁情报团队近期发现&#xff0c;名为“Patchwork”的黑客组织正以中国的大学和研究机构为目标进行活动&#xff0c;部署名为EyeShell的后门。 Patchwork也被称为“Operation Hangover”和“Zinc Emerson”&#xff0c;被怀疑是来自印度的APT组织。该组织发起…

d3dcompiler_47.dll缺失如何修复,教快速修复d3dcompiler_47.dll文件

在运行某些图形密集型应用程序或游戏时&#xff0c;你可能会遇到一条关于缺少d3dcompiler_47.dll文件的错误信息。这是一个常见的问题&#xff0c;今天我们主要就是来给大家讲解一下这方面的知识的&#xff0c;教大家怎么解决缺失d3dcompiler_47.dll的情况。 一. d3dcompiler_…

前端(十一)——Vue vs. React:两大前端框架的深度对比与分析

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;Vue vs. React&#xff1a;两大前端框架的深度对比与分析 文章目录 前言概述原理与设计思想算法生态系统与社区支持API与语法性能与优化开发体验与工程化对比总结结语 前言 在当今快速发展的前端领…

智能提词器有哪些?了解一下这款提词工具

智能提词器有哪些&#xff1f;使用智能提词器可以帮助你更好地准备和交付演讲、报告或其他提词场合。它可以提高你的效率&#xff0c;节省你的时间&#xff0c;并让你更加自信地与听众沟通。另外&#xff0c;智能提词器还可以提供一些有用的功能&#xff0c;如语音识别、智能建…

Jmeter用于接口测试中,关联如何实现

Jmeter用于接口测试时&#xff0c;后一个接口经常需要用到前一次接口返回的结果&#xff0c;应该如何获取前一次请求的结果值&#xff0c;应用于后一个接口呢&#xff0c;拿一个登录的例子来说明如何获取。 1、打开jmeter, 使用的3.3的版本&#xff0c;新建一个测试计划&#x…

C++和Lua交互总结

C和Lua交互总结 Chapter1. C和Lua交互总结一、Lua与C的交互机制——Lua堆栈二、堆栈的操作三、C 调用 Lua1&#xff09;C获取Lua值2&#xff09;C调用Lua函数示例&#xff1a; 四、Lua 调用 C包装C函数 最后总结一下 Chapter1. C和Lua交互总结 原文链接&#xff1a;https://bl…

无涯教程-Lua - 条件判断

if结构要求程序员确定一个或多个要由程序判断或测试的条件&#xff0c;以及要确定的条件为真的情况下要执行的一条或多条语句&#xff0c;如果条件为真&#xff0c;则执行指定语句&#xff0c;如果条件为假&#xff0c;则执行其他语句。 Lua编程语言假定布尔值 true 和 non-nil…

PHP高级检索功能的实现以及动态拼接sql

我们学习了解了这么多关于PHP的知识&#xff0c;不知道你们对PHP高级检索功能的实现以及动态拼接sql是否已经完全掌握了呢&#xff0c;如果没有&#xff0c;那就跟随本篇文章一起继续学习吧! PHP高级检索功能的实现以及动态拼接sql。完成的功能有&#xff1a;可以单独根据一个…