我在VC++ 2013,Windows 7-64,Intel i7 3.6 GHz.我想测量非常快速的数学运算的执行时间,例如我希望将标准fabsf()函数的性能与替代的"更快"方法或标准tanh()与Pade近似等进行比较.
问题是这些操作太快了,即使我运行它们数十万次,我总是在基准测试的结束和开始之间获得0毫秒.
我试着用纳秒来获得时间,<chrono>但是它被四舍五入到十分之一毫秒,而不是真正的纳秒,所以在我的基准测试中我仍然得到0纳秒.
你能提供一些代码片段,我可以用它来运行我的基准测试吗?
这是我的:
#include <vector>
#include <chrono>
#include <ctime>
using namespace std;
// 1/RAND_MAX
#define RAND_MAX_RECIP 0.00003051757f
int _tmain(int argc, _TCHAR* argv[])
{
srand (static_cast <unsigned> (time(0)));
// Fill a buffer with random float numbers
vector<float> buffer;
for (unsigned long i=0; i<10000000; ++i)
buffer.push_back( (float)rand() * RAND_MAX_RECIP );
// Get start time
auto start = std::chrono::high_resolution_clock::now();
for (unsigned long i=0; i<buffer.size(); ++i)
{
// do something with …Run Code Online (Sandbox Code Playgroud) 我编写了一个简单的程序来使用 RDTSC 指令测量代码执行时间。但是我不知道我的结果是否正确以及我的代码是否有问题......我不知道如何验证它。
#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#define N (1024*4)
unsigned cycles_low, cycles_high, cycles_low1, cycles_high1;
static __inline__ unsigned long long rdtsc(void)
{
__asm__ __volatile__ ("RDTSC\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low)::
"%rax", "rbx", "rcx", "rdx");
}
static __inline__ unsigned long long rdtsc1(void)
{
__asm__ __volatile__ ("RDTSC\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t": "=r" (cycles_high1), "=r" (cycles_low1)::
"%rax", "rbx", "rcx", "rdx");
}
int main(int argc, char* argv[])
{
uint64_t start, end;
rdtsc();
malloc(N); …Run Code Online (Sandbox Code Playgroud) 我编写了一个计时函数,记录了函数的运行时间,并计算了多次运行的均值和标准差。我惊讶地发现即使是看似简单的任务(例如加两个双打)也有很高的标准偏差。我分析了python中的数据(请参见图)。C ++输出是19.6171 ns +/- 21.9653ns (82799807 runs)使用以下命令编译的:
gcc version 8.3.0 (Debian 8.3.0-19)
/usr/bin/c++ -O3 -DNDEBUG -std=gnu++17
Run Code Online (Sandbox Code Playgroud)
整个测试是在我的个人计算机上完成的,该计算机不是空闲的而是运行DE,浏览器,IDE和其他进程。测试期间有可用的RAM。我的带有HT的双核CPU空闲率低于10%。
在这种情况下,是否会出现从20 ns的平均值到50 µs的峰值?
运行时间图
这是的内容std::vector<double> run_times。我没有看到任何图案。

定时
gcc version 8.3.0 (Debian 8.3.0-19)
/usr/bin/c++ -O3 -DNDEBUG -std=gnu++17
Run Code Online (Sandbox Code Playgroud)
计时文件
#include <cstdint>
#include <ostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <chrono>
#include <numeric>
#include <fstream>
struct TimingResults{
// all time results are in nanoseconds
double mean;
double standard_deviation;
uint64_t number_of_runs;
};
std::ostream& operator<<(std::ostream& os, const TimingResults& results);
template …Run Code Online (Sandbox Code Playgroud) 我在装配中经历了这个链接延迟,以增加装配延迟.我想通过添加不同的延迟值来执行一些实验.
生成延迟的有用代码
; start delay
mov bp, 43690
mov si, 43690
delay2:
dec bp
nop
jnz delay2
dec si
cmp si,0
jnz delay2
; end delay
Run Code Online (Sandbox Code Playgroud)
我从代码中理解的是,延迟与执行nop指令所花费的时间成比例(43690x43690).所以在不同系统和不同版本的操作系统中,延迟会有所不同.我对吗?
任何人都可以向我解释如何计算nsec的延迟量,下面的汇编代码正在生成,以便我可以结束我在实验设置中添加的延迟的实验?
这是我用来生成延迟而不理解使用43690值的逻辑的代码(我在原始源代码中只对一个循环使用了一个循环).为了产生不同的延迟(不知道它的值),我只改变了数字43690到403690或其他值.
32位操作系统中的代码
movl $43690, %esi ; ---> if I vary this 4003690 then delay value ??
.delay2:
dec %esi
nop
jnz .delay2
Run Code Online (Sandbox Code Playgroud)
这个汇编代码会产生多少延迟?
如果我想在microsec中生成100nsec或1000nsec或任何其他延迟,那么我需要在寄存器中加载什么初始值?
我使用的是ubuntu 16.04(32位和64位),Intel(R)Core(TM)i5-7200U CPU @ 2.50GHz和Core-i3 CPU 3470 @ 3.20GHz处理器.
先感谢您.
前一段时间,我问了一个关于堆栈溢出的问题,并展示了如何在C++中执行rdtsc操作码.我最近使用rdtsc创建了一个基准函数,如下所示:
inline unsigned long long rdtsc() {
unsigned int lo, hi;
asm volatile (
"cpuid \n"
"rdtsc"
: "=a"(lo), "=d"(hi) /* outputs */
: "a"(0) /* inputs */
: "%ebx", "%ecx"); /* clobbers*/
return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
}
typedef uint64_t (*FuncOneInt)(uint32_t n);
/**
time a function that takes an integer parameter and returns a 64 bit number
Since this is capable of timing in clock cycles, we won't have to do it a
huge …Run Code Online (Sandbox Code Playgroud) 我正在尝试计算运行单个ASM指令所需的CPU周期数。为了做到这一点,我创建了这个函数:
measure_register_op:
# Calculate time of required for movl operation
# function setup
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
xor %edi, %edi
# first time measurement
xorl %eax, %eax
cpuid # sync of threads
rdtsc # result in edx:eax
# we are measuring instuction below
movl %eax, %edi
# second time measurement
cpuid # sync of threads
rdtsc # result in edx:eax
# time difference
sub %eax, %edi
# move to EAX. Value of EAX is what …Run Code Online (Sandbox Code Playgroud) 我一直在玩一些 x64 程序集和 XMM 寄存器来做一些浮点数学,我看到一些让我感到困惑的性能。
作为自学练习,我编写了一些 SSE 程序集来近似“sin”函数(使用泰勒级数),并在循环中从一些基本的 C++ 调用它以与标准库版本进行比较。代码如下,之后我粘贴了一些典型运行的输出。(我不是在寻找对代码或方法的批评,只是想了解性能数字)。
我不明白的是为什么使用“发布”构建,其中实际运行的程序集是相同的(我已经通过调试器进行了仔细检查),始终慢了大约 40 - 50 个周期。(取消对 LFENCE 指令的注释会为 Debug 和 Release 增加大约 100 个周期,因此增量保持不变)。作为一个额外的问题,为什么第一次迭代通常是数千次!!
我知道这些东西非常复杂,并且受到许多因素的微妙影响,但是作为潜在原因出现在我脑海中的一切都是没有意义的。
我已经在两次运行中检查了 MSCSR 标志,这在构建中也是相同的(默认值为 1f80h,它屏蔽了所有异常)。
知道什么会导致这种情况吗?我可以做哪些进一步的分析来更深层次地解决这个问题?
集会
_RDATA segment
pi real4 3.141592654
rf3 real4 0.1666666667
rf5 real4 0.008333333333
rf7 real4 0.0001984126984
_RDATA ends
_TEXT segment
; float CalcSin(float rads, int* cycles)
CalcSin PROC
; "leaf" function - doesn't use the stack or any non-volatile registers
mov r8, rdx ; Save the 'cycles' pointer …Run Code Online (Sandbox Code Playgroud) 我正在评估我的项目的网络+渲染工作负载。
程序连续运行一个主循环:
while (true) {
doSomething()
drawSomething()
doSomething2()
sendSomething()
}
Run Code Online (Sandbox Code Playgroud)
主循环每秒运行 60 多次。
我想查看性能故障,每个程序需要多少时间。
我担心的是,如果我打印每个程序的每个入口和出口的时间间隔,
这会导致巨大的性能开销。
我很好奇什么是衡量性能的惯用方法。
日志打印是否足够好?
考虑两个线程,T1 和 T2,它们分别存储和加载一个原子整数 a_i。让我们进一步假设,这家店在执行前正在执行的负荷启动。以前,我的意思是绝对的时间意义。
T1 T2
// other_instructions here... // ...
a_i.store(7, memory_order_relaxed) // other instructions here
// other instructions here // ...
a_i.load(memory_order_relaxed)
// other instructions here
Run Code Online (Sandbox Code Playgroud)
是否保证T2在加载后看到值7?
我写了一些代码来测量每个字节的 CPU 周期。我变得消极,cpb但不知道为什么......它告诉我cpb = -0.855553 cycles/byte
我的伪代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
uint64_t rdtsc(){
unsigned int lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}
int main()
{
long double inputsSize = 1024;
long double counter = 1;
long double cpuCycleStart = rdtsc();
while(counter < 3s)
function(args);
long double cpuCycleEnd = rdtsc();
long double cpb = ((cpuCycleEnd - cpuCycleStart) / (counter * inputsSize));
printf("%Lf cycles/byte\n", cpb);
return …Run Code Online (Sandbox Code Playgroud) 抱歉,我没有具体说明问题,我需要一种方法来计算我的算法所需的确切时钟周期数,用 C 编写,
->我尝试了clock()和Windows特定函数,如QueryPerformanceCounter(),它们都没有在每次运行时给我准确的时钟周期。
对于相同的输入,我每次运行都会得到完全不同的值。
如果您建议任何以时钟周期为单位查找执行时间的方法,并且每次运行都不会改变,那将非常有帮助。
硬件:我的是intel i5处理器,运行在windows 10操作系统下。
我不知道这段代码究竟是什么:
int rdtsc(){
__asm__ __volatile__("rdtsc");
Run Code Online (Sandbox Code Playgroud)
拜托,有人可以解释一下吗?为什么"rdtsc"?