我已经在C中实现了http://primates.ae/中的PRIMATEs密码的一些切片实现。我使用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编译代码,这没有区别(GCC比/ O2或/ O3快1%左右;不记得哪个)。我正在使用英特尔Turboboost和超线程关闭的一个核心上运行测试。
我的完整源代码在这里: https://github.com/opolo/Bitsliced-AEAD/tree/master/Primates/APE120_Bitsliced 我的测试套件在Ref.c中,而位切片排列在Primate.c中...代码现在不是超级清洁,我的不好。这就是为什么我之前尝试给出一个例子而不仅仅是完全使用我的代码。
答案 0 :(得分:2)
使用_rdtsc()测量每个字节的周期是错误的吗?
不,这是正确的方法。我更喜欢使用内联汇编来rdtsc
指令来保证内联。这是一个依赖于实现的功能,所以你真的不知道发生了什么。特别是你不知道它是否正确地防止了无序执行。见here for an inline asm solution。我不知道x86内在函数是做什么的。
原因可能是我没有测量专门用于代码的时钟周期,而是整个系统?
是的,函数调用有一些开销。通常在现代平台上存在O(100)时钟节拍开销。如果你的数据集足够大,那真的不重要吗。
我可以在Windows上运行它而不是例如linux有很大的不同吗?
罗
所以你没有从算法中获得你想要的性能?这一切都取决于你的实施方式,所以我不会责怪你的计时功能。完善算法实现有许多复杂性。如果您使用内联asm或内在函数显式地向量化了内容,请注意,与标准C和优化编译器相比,较差或过度抽象的实现可能会表现得更差。一种好的方法是首先编写算法的C实现作为基准和验证,然后手动开始优化。
加密/解密功能在哪里?