我已经在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);

我相信我正在正确执行计算,所以我想知道...
  • 使用_rdtsc()测量每个字节的周期是否错误?
  • 可能是因为我不是测量仅花费在我的代码上而是整个系统上的时钟周期吗? (我不知道,如果能看到在那种情况下我的代码花了多少钱)
  • 我可以在Windows而不是例如Windows上运行它linux有很大的不同吗?

  • 我试过用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/

    10-12 16:15