为什么Crypto ++中的AES代码提供不同的性能结果?
我想测试AES加密的性能。但是每当我运行代码时,它都会给出不同的结果。为什么? 下面是在C++中使用加密++代码:为什么Crypto ++中的AES代码提供不同的性能结果?
int main(int argc, char* argv[]){
AutoSeededRandomPool prng;
byte key[AES::DEFAULT_KEYLENGTH];
prng.GenerateBlock(key, sizeof(key));
byte iv[AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
CBC_Mode<AES>::Encryption e;
e.SetKeyWithIV(key, sizeof(key), iv);
CBC_Mode<AES>::Decryption d;
d.SetKeyWithIV(key, sizeof(key), iv);
时间测试是在这里:
clock_t startTime, finishTime;
std::string plain = "AES CBC Test";
std::string cipher, encoded, recovered;
startTime = clock();
try
{
// The StreamTransformationFilter removes
// padding as required.
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
) // StreamTransformationFilter
); // StringSource
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
exit(1);
}
// save current time just after finishing the encryption loop
finishTime = clock();
和我的测试结果在这里:
enter code heredouble executionTimeInSec = double(finishTime - startTime)/CLOCK_TICKS_PER_SECOND;
std::cout << "Encryption loop execution time: " << executionTimeInSec * 1000.0 << " microseconds." << std::endl;
std::cout << "Plain text size: " << plain.size() << " bytes." << std::endl;
double data_rate_MiBps = ((double)plain.size()/1048576)/((double)executionTimeInSec) ;
std::cout << "Encryption/decryption loop execution time MB/S: " << data_rate_MiBps << " MB/S." << std::endl;
return 0;}
时序优化调试版本。 编译结果1:
加密循环执行时间:0.041微秒。
编译结果2:
加密循环执行时间:0.057毫秒。
0.041微秒的测试时间太短。要获得可靠的测量,您需要对测试执行多次迭代,然后将总时间除以您所做的迭代次数。
当在这么短的时间内测量框架许多因素会弄乱你的计时:
- 您的系统时钟的分辨率可能没有足够高的在你的措施给予相对大的跳跃。
- 您的计时只测量经过时间,而不是在CPU上运行的实际时间。操作系统在一次测试中将CPU分配给其他测试而不是另一次测试的影响会引发测量中的大幅波动。在进行多次迭代时,您可以在许多迭代中平滑此随机影响,从而消除偶然性的影响。
- 等等
相关的加密+标杆,该库在cryptest.exe
提供了一个基准测试套件。你像下面那样调用它。 b
表示基准; 3
表示运行测试3秒; 2.4
表示CPU频率为2.4 GHz。
./cryptest.exe b 3 2.4
下面的命令produces output similar to。
你可以在bench1.cpp
和bench2.cpp
找到源代码。对于AES,您需要检查bench2.cpp
。下面的代码负责生成数字:
void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal)
{
const int BUF_SIZE=RoundUpToMultipleOf(2048U, cipher.OptimalBlockSize());
AlignedSecByteBlock buf(BUF_SIZE);
Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
unsigned long i=0, blocks=1;
double timeTaken;
clock_t start = ::clock();
do
{
blocks *= 2;
for (; i<blocks; i++)
cipher.ProcessString(buf, BUF_SIZE);
timeTaken = double(::clock() - start)/CLOCK_TICKS_PER_SECOND;
}
while (timeTaken < 2.0/3*timeTotal);
OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
}
之前要调用BenchMark
与StreamTransformation
,工厂方法所创建的AES对象,并键入它进行测试。
一些基准代码最近被更改了,但它主要是化妆品。最大的变化是增加了随机数发生器来测试它们的表现。另请参阅用户列表中的RNG Benchmarks and rework of RDRAND/RDSEED。
当进行基准测试时,您还应该记住Turbo Boost和其他相关技术的影响。如果您的CPU运行在3.5 GHz,但在3.8 GHz时爆发,则会影响预期吞吐量。有时候,它会使基准成为一个移动目标,而在其他时候,它可能会解释为什么你超过了理论最大值。
突发只是一个内部超频。英特尔多年来一直这样做。他们过去称之为旧版P5 Pentium中的NetBurst。通过使用支持超频的主板和处理器,硬件人员和玩家一直在努力。
这将有助于你的答案的机会,如果你的代码实际上编译。 –
您还应该发布是否计时优化的发布版本或未优化的“调试”版本。如果是后者,那么这些时间是没有意义的。 – PaulMcKenzie
另请参阅[如何在Crypto ++库基准测试中运行?](http://*.com/q/29264531/608639)和[AES/CBC加密与解密之间的速度差异?](http:// *。 com/q/20164502/608639) – jww