如何测试我生成的汇编程序?

How to test my generated assembly program?

我制作了一个程序,它根据参数为我的矢量扩展生成汇编指令以执行卷积。请注意,我假设我的向量扩展没有循环或分支指令

但是,如果我设置输入宽度= 7,内核宽度= 3,输入通道= 128,输出通道= 4,那么生成的指令数将近90,000。我有这个矢量处理器的指令模拟器,但我不知道如何检查我生成的指令是否正常。

有什么好的起点或好的主意吗?

显而易见的是 运行 使用一些完全随机的测试输入,并与具有相同数据输入的简单已知良好实施的结果进行比较。 (例如,用 C 或您最喜欢的高级语言编写,可能只是 运行 在主机 CPU 上,而不是在模拟器内)。 运行在你的模拟器中安装一个简单的实现也很好,或者如果这样更容易的话。

当您比较结果时,如果您的简单实现使用不同的操作顺序,您可能需要为 FP 舍入误差留出一些回旋余地。就像一个非常标准的事情是检查绝对差异是否都在 1e-7 之内,或者检查相对差异(尽管相对误差对于减法产生的接近零的数字可能很大;灾难性取消是一个已知问题FP).

(如果您还没有意识到这些问题,另请参阅 https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ 和 Bruce 的 FP 系列文章的其余部分。)

也许值得拥有一个以双精度计算的参考实现,这样在评估具有舍入误差的计算时,您可以更好地了解实际正确答案是什么。


当数据不匹配参考时进行调试:

用非常简单的输入数据再次测试,像所有0.0一样,除了一个元素中的1.0 .这可能会突出显示错误的数组索引问题。或全部 1.0,或全部 -2.0.

或者一些输入应该产生一个非常简单的输出,对于你试图实现的已知算法。例如如果大多数输出​​应该是 0.0,看看哪些不是,或者它们有什么价值,可能是一个很大的提示。


另请注意,大多数现实世界 CPU 都有某种指令缓存,因此通常值得一点点循环开销(大展开循环)来回收适合缓存的循环体,而不是 完全 将循环展开/剥离成一大块直线代码。 (好像 90k 条指令听起来太多了)。但是,如果真的没有任何简单的重复可以通过展开来摊销,那么值得考虑一下。