C++ 测量算法的每字节循环数

C++ 测量算法的每字节循环数,c++,c,gcc,benchmarking,simd,C++,C,Gcc,Benchmarking,Simd,我已经实现了C语言中灵长类密码的一个切片实现。我使用SIMD编程,所以我在代码中使用了AVX2指令集 我目前正试图准确地衡量我的实施有多有效,但我并不真的相信目前的数字,我得到了。根据我目前的数字,每个字节大约有200个周期,这似乎比密码的周期要长 目前,我的代码如下所示 #typedef u64 unsigned long long u64 start, finish; u64 samples[1000000]; data = calloc(4000, sizeof(unsigned cha

我已经实现了C语言中灵长类密码的一个切片实现。我使用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);
#typedef u64无符号长
u64开始,结束;
u64样本[1000000];
data=calloc(4000,sizeof(无符号字符));
//在单核上进行性能测试,因为这是计算周期/字节时的标准。
SetThreadAffinityMask(GetCurrentThread(),0x00000008);
//查找CPU时钟速度
开始=_rdtsc();
睡眠(1000);
finish=_rdtsc();
cpu_频率=完成启动;
//采集大量样本,并使用这些样本的中值。
对于(int i=0;i<1000000;i++){
开始=_rdtsc();
加密(数据);
解密(数据);
finish=_rdtsc();
样本[i]=完成-开始;
}
qsort(样品);
u64中值=样本[500000];
每字节双周期=1/(4000.00/中位数);
我相信我的计算是正确的,所以我想知道

  • 使用_rdtsc()测量每个字节的周期是否错误
  • 原因可能是我没有专门测量代码上的时钟周期,而是整个系统上的时钟周期?(我不知道,如果我能看到在这种情况下,我的代码花了多少钱)
  • 我在Windows上运行它而不是在linux上运行它这一事实会有很大的不同吗
我尝试过用GCC和MSVC编译代码,两者没有区别(用/O2或/O3编译GCC大约快1%;不记得是哪个)。我只在一个内核上运行测试,Intel Turboboost和Hyperreading已关闭

我的完整源代码如下: 我的测试套件在Ref.c中,而位切片排列在Primate.c中。。。代码现在不是超级清洁,我的错。这就是为什么我以前试着给出一个例子,而不仅仅是完全c/p我的代码

使用_rdtsc()测量每个字节的周期是否错误

不,这是正确的方法。我更喜欢对
rdtsc
指令使用内联汇编来保证内联。这是一个依赖于实现的函数,因此您不知道发生了什么。特别是,您不知道它是否正确地防止了无序执行。看见我不知道x86内部函数做什么

原因可能是我没有专门测量代码上的时钟周期,而是整个系统上的时钟周期

是的,函数调用有一些开销。在现代平台上,通常会有一个0(100)的时钟滴答声。如果您的数据集足够大,这并不重要

我在Windows上运行它而不是在linux上运行它这一事实会有很大的不同吗


所以你没有从算法中获得你想要的性能?这一切都取决于您的实现方式,因此我不会直接责怪您的计时功能。完善算法实现有许多复杂的步骤。如果您使用内联asm或intrinsic显式地对内容进行了矢量化,请注意,与标准C和优化编译器相比,一个糟糕的或过度抽象的实现可能会执行得更差。一个好的方法是首先编写算法的C实现作为基准和验证,然后开始手动优化


加密/解密功能在哪里?

这是为了找出
\u rdtsc
measures.Hi。谢谢你的回答。我毫不怀疑rdtsc的测量结果。如果我读取cpu_频率变量,我可以看到它的值与我的cpu时钟速度匹配,因此它必须是周期计数。然而,与其他密码相比,我的循环/字节计数确实很大,这一事实让我怀疑使用它是否是错误的。如果它可能在多核环境中出现问题,或者是因为我没有专门测量花在代码上的CPU周期(如果其他人这样做的话)。我还没有找到使用Windows API调用进行的其他周期/字节码测量(例如_rdtsc())。做一个快速的健全性检查很容易——用你的密码处理一大块数据——足够大,处理大约需要10秒。然后测量“挂钟”时间和除以数据中的字节数。这应该会给你一个数字,你可以相信它是正确的-如果它与你的
\u rdtsc
测量值非常不同,那么你就知道你做错了什么(反之亦然).哦,现在我明白你的意思了。你知道你不仅仅是在测量你自己进程的周期,而是想知道这是否是产生大量数字的原因(对吗?)。抱歉,我很困惑。(我想说这确实是原因,但我对Windows的了解还不够多,无法回答。)围绕
sleep()调用
rdtsc
不是在多处理器机器中寻找时钟速度的明智方法。
sleep()
可能会导致操作系统将程序调度出去,而您不知道它是否会被调度回同一处理器(或处理器核心).非常晚的回答-抱歉。那几个月压力很大。长话短说,你的回答真的帮了我的忙,所以值得感谢:谢谢!!我的论文需要它,我最终得了a。可以说部分是因为这个答案。我最终使用了rdtsc()只要按照你的建议把我的数据集设置得足够大,并多次执行相同的操作,使速度上的微小差异可以忽略。结果很好!