在编译时评估函数成本的通用方法
generic way to evaluate a function cost at compile time
我目前正在研究多维数组迭代器的实现。考虑到代表具有不同对齐方式(二维中的行与主要列)的兼容数据的两个连续范围(用于 std::equal、std::copy 目的)的迭代,我想找到每个迭代器给出的步幅顺序最快的执行时间。
例如:
row of vector components = A -> m elements
row of vectors = B -> n elements
2D plan of vectors = C -> 3 elements
row of plan of vectors = D -> 10 elements
given the datas ordered by ascending strides:
first array: B | A | C | D
second array: B | A | D | C
Obviously, we can iterate over both iterators by bunches of m*n elements. Then:
If we choose the first array convention, the first iterator is contiguous and the second one
will perform (3 - 1)*(10 - 1) jumps forward with a stride of 10 and (10 - 1) jumps backward.
If we choose the second array convention, the second iterator is contiguous and the first one will
perform (10 - 1)*(3 - 1) jumps forward with a stride of 3 and (3 - 1) jumps backward.
=> The second convention is better at everything in this example.
由于我必须考虑很多因素,如内存来回、连续性和迭代器实现本身(这不是微不足道的),我想执行一个实验计划。但我也知道编译时的所有内容(大小和步幅),因此在编译时为每个模板实例化执行实验计划会很酷。我的问题是:
是否可以在编译时评估某些指令的运行时成本,因为除了输入数组的内存地址之外的所有内容在编译时都是已知的?
没有。你的问题是基于错误的假设。
一些错误的假设(可能还有其他假设):
- 函数按原样使用:编译器可能会在很多地方内联它,或者决定最好将它放在一个单独的函数中,因为代码大小会增加。由于周围代码的行为可能略有不同,因此您可能会看到不同的性能。
- 一条指令是有成本的:处理器 运行 指令在许多情况下是乱序的,或者它们并行化了指令。如果它被其他内存访问包围并且得到它的成本摊销,那么可能需要很长时间的东西(如除法)可能会被隐藏。
- 性能与处理器无关。编译器不知道您要 运行 使用哪个特定处理器、高速缓存或高速缓存行有多大、主内存有多快或 good/bad 分支预测将如何。所有这些都对性能产生巨大影响。
您可以做的是剖析和测量。使用此功能分析应用程序,看看您是否真的需要修复它。衡量您获得的性能并尝试不同的选项。
我目前正在研究多维数组迭代器的实现。考虑到代表具有不同对齐方式(二维中的行与主要列)的兼容数据的两个连续范围(用于 std::equal、std::copy 目的)的迭代,我想找到每个迭代器给出的步幅顺序最快的执行时间。
例如:
row of vector components = A -> m elements
row of vectors = B -> n elements
2D plan of vectors = C -> 3 elements
row of plan of vectors = D -> 10 elements
given the datas ordered by ascending strides:
first array: B | A | C | D
second array: B | A | D | C
Obviously, we can iterate over both iterators by bunches of m*n elements. Then:
If we choose the first array convention, the first iterator is contiguous and the second one
will perform (3 - 1)*(10 - 1) jumps forward with a stride of 10 and (10 - 1) jumps backward.
If we choose the second array convention, the second iterator is contiguous and the first one will
perform (10 - 1)*(3 - 1) jumps forward with a stride of 3 and (3 - 1) jumps backward.
=> The second convention is better at everything in this example.
由于我必须考虑很多因素,如内存来回、连续性和迭代器实现本身(这不是微不足道的),我想执行一个实验计划。但我也知道编译时的所有内容(大小和步幅),因此在编译时为每个模板实例化执行实验计划会很酷。我的问题是:
是否可以在编译时评估某些指令的运行时成本,因为除了输入数组的内存地址之外的所有内容在编译时都是已知的?
没有。你的问题是基于错误的假设。
一些错误的假设(可能还有其他假设):
- 函数按原样使用:编译器可能会在很多地方内联它,或者决定最好将它放在一个单独的函数中,因为代码大小会增加。由于周围代码的行为可能略有不同,因此您可能会看到不同的性能。
- 一条指令是有成本的:处理器 运行 指令在许多情况下是乱序的,或者它们并行化了指令。如果它被其他内存访问包围并且得到它的成本摊销,那么可能需要很长时间的东西(如除法)可能会被隐藏。
- 性能与处理器无关。编译器不知道您要 运行 使用哪个特定处理器、高速缓存或高速缓存行有多大、主内存有多快或 good/bad 分支预测将如何。所有这些都对性能产生巨大影响。
您可以做的是剖析和测量。使用此功能分析应用程序,看看您是否真的需要修复它。衡量您获得的性能并尝试不同的选项。