首页 > 解决方案 > 在基准测试期间,加密功能似乎并没有始终如一地执行;chrono 记录没有经过的时间

问题描述

因此,我正在使用 std::chrono 库对我自己的 AES 和 3DES 密码以及 CBC 和 OFB 操作模式的类项目实现进行基准测试。基本设置是:

chrono::steady_clock::time_point t0 = chrono::steady_clock::now();
MODECALL_E (ptext, key);
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
MODECALL_D (ptext, key);
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();

其中 MODECALL_E/D 是我在编译时更改为我要进行基准测试的任何函数的宏(特别是操作模式函数,它将密码函数作为模板参数,然后在内部调用它)。然后我循环这段代码并记录加密和解密所花费的时间,通过强制转换为 chrono::microseconds:

timing_return ret;
ret.etime = chrono::duration_cast<chrono::microseconds> (t1 - t0);
ret.dtime = chrono::duration_cast<chrono::microseconds> (t2 - t1);

然后我将 etime.count() 和 dtime.count() 存储在输出文件中。

然而,在这两种操作模式下,相当数量的 AES 密码运行记录为零时间,有时用于加密,有时用于解密。我还尝试转换为纳秒以确保它不仅仅是一个分辨率问题,并且仍然有很多零条目,所以很明显有些东西无法正常运行。仅供参考,加密 4 KB 文本文件的典型时间(因密钥大小而异)在 10-15 毫秒范围内。

我在 GDB 中运行了代码,并在被调用函数中放置了一个忽略的断点来计算命中次数,然后……所有零条目都消失了(并且函数被命中了正确的次数)。这似乎是断点的结果,因为我最初只是在加密函数中设置了一个断点,并且仍然有零个用于解密的条目,然后当我在解密函数中添加一个断点时它就消失了。不幸的是,GDB 还增加了运行时间的显着开销,所以我不能只在其中运行基准测试。

我真的被这个难住了,有人知道发生了什么吗?我使用 -O3 编译了代码;可能是某种优化以某种方式跳过了函数的运行吗?请注意,这只发生在 AES 密码中,而不是 3DES,但它发生在 CBC 和 OFB 模式中。

如果您还想查看其他内容,可以在https://github.com/georgehodgkins/ECE5397project找到完整的实现代码(相当广泛),包括基准测试代码。

标签: c++encryptionbenchmarkingchrono

解决方案


推荐阅读