Bench模板库
简介
本项目的目标是比较现有数值库的性能。代码被设计得尽可能通用和模块化。因此,添加新的数值库或新的数值测试应需付出最小的努力。
安装
BTL使用cmake/ctest
1 - 创建一个构建目录
mkdir build & cd build
2 - 配置
ccmake ..
3 - 使用ctest运行基准测试
ctest -V
您可以在匹配给定正则表达式的库上运行基准测试:ctest -V -R 例如:ctest -V -R eigen2
您也可以通过设置环境变量BTL_CONFIG来选择一组操作以定义一个给定的子集:BTL_CONFIG="-a action1{:action2}*" ctest -V 示例:BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata" ctest -V -R eigen2
最后,如果基准结果已经存在(bench*.dat文件),则将它们合并并保持每个矩阵大小中的最佳结果。如果要覆盖先前的结果,可以简单地添加“--overwrite”选项:BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata --overwrite" ctest -V -R eigen2
4 : 分析结果。每个库目录中产生不同的数据文件(.dat)。如果gnuplot可用,请选择数据目录中的一个目录名来存储结果,并输入:
文件和目录
generic_bench : 所有库共用的测试源代码
actions : 测试动作包装器(axpy、矩阵-矩阵产品)的源代码。
libs/* : 每个测试库的特定测试源代码。
machine_dep : 用于存储机器特定的Makefile.in的目录
data : 存储gnuplot脚本和数据分析工具的目录
原则:通过定义以下两个概念实现了代码的模块化
****** 动作概念:这是一个定义必须执行哪些测试(例如,矩阵乘法向量)的类。动作应定义以下方法
*** Ctor using the size of the problem (matrix or vector size) as an argument
Action action(size);
*** initialize : this method initialize the calculation (e.g. initialize the matrices and vectors arguments)
action.initialize();
*** calculate : this method actually launch the calculation to be benchmarked
action.calculate;
*** nb_op_base() : this method returns the complexity of the calculate method (allowing the mflops evaluation)
*** name() : this method returns the name of the action (std::string)
****** 接口概念:这是一个定义如何使用给定库及其特定容器(矩阵和向量)的类或命名空间。到目前为止,接口应遵循以下类型
*** real_type : kind of float to be used (float or double)
*** stl_vector : must correspond to std::vector<real_type>
*** stl_matrix : must correspond to std::vector<stl_vector>
*** gene_vector : the vector type for this interface --> e.g. (real_type *) for the C_interface
*** gene_matrix : the matrix type for this interface --> e.g. (gene_vector *) for the C_interface
+ the following common methods
*** free_matrix(gene_matrix & A, int N) dealocation of a N sized gene_matrix A
*** free_vector(gene_vector & B) dealocation of a N sized gene_vector B
*** matrix_from_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an stl_matrix A_stl into a gene_matrix A.
The allocation of A is done in this function.
*** vector_to_stl(gene_vector & B, stl_vector & B_stl) copy the content of an stl_vector B_stl into a gene_vector B.
The allocation of B is done in this function.
*** matrix_to_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an gene_matrix A into an stl_matrix A_stl.
The size of A_STL must corresponds to the size of A.
*** vector_to_stl(gene_vector & A, stl_vector & A_stl) copy the content of an gene_vector A into an stl_vector A_stl.
The size of B_STL must corresponds to the size of B.
*** copy_matrix(gene_matrix & source, gene_matrix & cible, int N) : copy the content of source in cible. Both source
and cible must be sized NxN.
*** copy_vector(gene_vector & source, gene_vector & cible, int N) : copy the content of source in cible. Both source
and cible must be sized N.
and the following method corresponding to the action one wants to be benchmarked :
*** matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
*** matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)
*** ata_product(const gene_matrix & A, gene_matrix & X, int N)
*** aat_product(const gene_matrix & A, gene_matrix & X, int N)
*** axpy(real coef, const gene_vector & X, gene_vector & Y, int N)
基准算法(generic_bench/bench.hh)用动作本身用接口模板化进行模板化。在给定库目录libs/A_LIB中存储的典型main.cpp源代码如下:
bench < AN_ACTION < AN_INTERFACE > > (10, 1000, 50);
此函数将生成一个XY数据文件,其中包含以大小为10000和10之间的大小50个不同的测量值,作为大小的函数的mflops。
此算法可以通过提供给定的 Perf_Analyzer 对象来进行适配,该对象确定时间测量的方式。例如,X86_Perf_Analyzer 使用 asm rdtsc 函数提供一个非常快速且精确的(但不太便携的)计时方法。默认情况下是 Portable_Perf_Analyzer,因此
bench < AN_ACTION < AN_INTERFACE > > (10, 1000, 50);
等价于
bench
如果您的系统支持,我们建议使用混合实现(X86_perf_Analyzer+Portable_Perf_Analyzer)。将 generic/bench.hh 中的 bench(size_min,size_max,nb_point); 替换为 bench(size_min,size_max,nb_point);
.