我已经在C中的http://primates.ae/中实现了PRIMATEs密码的一些 slice 实现。我已经使用SIMD编程来实现它,因此我在代码中使用了AVX2指令集。
我目前正在尝试准确地衡量我的实现效果,但是我不太相信当前的数字。根据我目前的数字,我每个字节大约得到200个周期,这似乎比密码得到的结果还差。
目前,我的代码如下所示
#typedef u64 unsigned long long
u64 start, finish;
u64 samples[1000000];
data = calloc(4000, sizeof(unsigned char));
//Performance test on a single core, as that is the standard when computing cycles/byte.
SetThreadAffinityMask(GetCurrentThread(), 0x00000008);
//Find CPU clock speed
start = _rdtsc();
sleep(1000);
finish = _rdtsc();
cpu_frequency = finish-start;
//Take a lot of samples and use median of these.
for (int i = 0; i < 1000000; i++){
start = _rdtsc();
encrypt(data);
decrypt(data);
finish = _rdtsc();
samples[i] = finish - start;
}
qsort(samples);
u64 median = samples[500000];
double cycles_per_byte = 1 / (4000.00 / median);
我相信我正在正确执行计算,所以我想知道...
我试过用GCC和MSVC编译代码,两者没有什么区别(使用/ O2或/ O3时,GCC的速度提高了大约1%;不记得是哪一个)。我在Intel Turboboost和超线程关闭的情况下仅在一个内核上运行测试。
我完整的源代码在这里:
https://github.com/opolo/Bitsliced-AEAD/tree/master/Primates/APE120_Bitsliced
我的测试套件位于Ref.c中,而位片排列的置换位于Primate.c中……代码现在还不是很干净,我很糟糕。这就是为什么我尝试给出一个示例,而不仅仅是完全c / p我的代码。
最佳答案
不,这是正确的方法。我更喜欢将内联汇编用于rdtsc
指令以保证内联。这是一个依赖于实现的函数,因此您真的不知道发生了什么。特别是您不知道它是否正确地防止了乱序执行。参见here for an inline asm solution。我不知道x86内部函数做什么。
是的,函数调用会有一些开销。在现代平台上,通常会有O(100)时钟滴答开销。如果您的数据集足够大,那并不重要。
h
因此,您没有从算法中获得想要的性能吗?这一切都取决于您的实现方式,因此我不会责怪您的计时功能。完善算法实现有许多复杂的步骤。如果您已经使用内联asm或内在函数对 vector 进行了显式矢量化,请注意,较差的或过度抽象的实现可能会比标准C和优化的编译器性能差。一个好的方法是首先编写该算法的C实现作为基准和验证,然后开始手动进行优化。
加密/解密功能在哪里?
关于c++ - 测量算法的每字节周期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38055167/