How to correctly measure the running time of an opencl program - opencl

When I used opencl to test the performance of the program, I encountered some doubts. The original intention of our experiment was to test the calculation time of the program, but there were some problems in the actual process. In the following code, timex uses the method of binding events to calculate the results. However, in the actual results, we found that (end_time - start_time) < time1+time2+time3 . We don't know why, and we're also curious how exactly we should calculate the running time of the task.
start_time = clock()
compute(){
writeData(); // time1
clEnqueueNDRangeKernel(); // time2
readData(); //time3
do_other();
}
end_time = clock()

It depends on what exactly you want to measure. If it is just for profiling, you could be interested in time1, time2 and time3 separately. If it is for measuring the performance of the compute(), you want to measure its entire runtime.
To measure time with nanosecond precision, use this clock:
#include <chrono>
class Clock {
private:
typedef chrono::high_resolution_clock clock;
chrono::time_point<clock> t;
public:
Clock() { start(); }
void start() { t = clock::now(); }
double stop() const { return chrono::duration_cast<chrono::duration<double>>(clock::now()-t).count(); }
};
In your example, the issue with (end_time-start_time) < time1+time2+time3 may have two possible reasons:
Your clock implementation is not accurate enough and it is just rounding error.
You didn't use clFinish(queue);. The OpenCL commands are only enqueued, but not executed right away. So clEnqueueNDRangeKernel(); for example immediately returns, and if you measure time before and time after, you get practically 0. To wait until the Kernel really has been executed, you need to call clFinish afterards.
Example:
Measure time1, time2 and time3 separately:
compute() {
//clFinish(queue); // if there could still be stuff in the queue, finish it first
Clock clock;
clock.start();
writeData(); // time1
clFinish(queue);
const double time1 = clock.stop(); // in seconds
clock.start();
clEnqueueNDRangeKernel(); // time2
clFinish(queue);
const double time2 = clock.stop(); // in seconds
clock.start();
readData(); //time3
clFinish(queue);
const double time3 = clock.stop(); // in seconds
do_other();
clFinish(queue); // don't forget to finish the queue!
}
To measure the entire execution time of compute(), you only need one clFinish at the end.
compute() {
//clFinish(queue); // if there could still be stuff in the queue, finish it first
Clock clock;
clock.start();
writeData(); // time1
clEnqueueNDRangeKernel(); // time2
readData(); //time3
do_other();
clFinish(queue); // don't forget to finish the queue!
const double time = clock.stop(); // in seconds
}

Related

Run two functions at once

This program is a simple program designed to plot at the same time both your & Uc on the serial monitor. Arduino runs through the first for loop & plot the F1 function and after that does the same with F2. My objective is to plot them both at the same time.
My idea is to actually take a small fraction of time, let's say 10 ms, to plot F1 & the next 10 ms to plot F2, but I don't know how to write this down. I think the millis function is the solution, but I'm not quite sure how to implement it.
const short int R = 5000;
const float C = 0.0005;
const float TE = 0.1;
const float Tau = R*C;
const short int E = 5;
float t, Tinit,Tfin;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
//F1
for ( t = 0; t <= 20; t = t+TE)
{
float Ur = E*exp(-t/Tau);
Serial.println (Ur);
}
//F2
for ( t = 0; t <= 20; t = t+TE)
{
float Uc = E*(1-exp(-t/Tau));
Serial.println (Uc);
}
}
Thread can be used to solve your problem . It has a huge documentation , it is widely used library for Arduino(unofficial).
Give it a try.
It will be easy for you, if you see these :
Example - 1 (thread instance example)
Example - 2 (callback example)
Example - 3 (It is still buggy , but I think it will help)
If you want to do it without libraries , then you need to create two functions , without those loops . Like
void f1()
{
float Ur = E*exp(-t/Tau);
Serial.println (Ur);
}
void f2()
{
float Uc = E*(1-exp(-t/Tau));
Serial.println (Uc);
}
Now inside "void loop()" you can implement the basic logic of threading , which will be pretty rough , but fulfill your requirements. Like :
void loop() {
unsigned long now = millis();
static unsigned long last_finger_update;
if (now - last_finger_update >= FINGER_UPDATE_PERIOD) {
last_finger_update = now;
f1();
}
static unsigned long last_wrist_update;
if (now - last_wrist_update >= WRIST_UPDATE_PERIOD) {
last_wrist_update = now;
f2();
}
}
You have to declare two variables
const unsigned long FINGER_UPDATE_PERIOD = 1000;
const unsigned long WRIST_UPDATE_PERIOD = 1000;
All time units are in milliseconds. This strategy is collected from internet.
The most deterministic way of handling this is simply:
for (t = 0; t <= 20; t = t + TE) {
float Ur = E*exp(-t/Tau);
float Uc = E*(1-exp(-t/Tau));
Serial.println (Ur);
Serial.println (Uc);
}
More generally, you can implement a primitive resource scheduler:
while (true) {
task_one();
task_two();
}
You can do that Easily if you run RTOS in MCU as you know other solutions will also be sequential...
I've been using TridentTD_EasyFreeRTOS library it has easy way of having multiple tasks and controlling them in different sketch files..

Wait for QGLWidget to finish rendering

I'm developing an OpenGL benchmark for a Qt application using VBOs and not glBegin/glEnd stuff.
I call the the class GLWidget (that inherits from public QGLWidget and protected QGLFunctions) from the MainWindow and I want to wait for the rendering to finish and get the value of the variable that stores the time elapsed. Problem is I don't find a suitable SIGNAL / method of waiting for the finish of a QGLWidget, so I get wrong variable values from MainWindow even if I use glFinish() at the end of the rendering.
void GLWidget::initializeGL() {
// VBO, glGenBuffers, glBindBuffer, glBufferData stuff
}
void GLWidget::paintGL()
{
QGLFunctions::glEnableVertexAttribArray(0);
QGLFunctions::glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
QGLFunctions::glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
// Start Time
startTime = clock();
glDrawArrays(GL_TRIANGLES, 0, numVertices);
// Wait for the rendering
glFinish();
// Finish Time
finishTime = clock();
relativeTime = finishTime - startTime;
totalTime = (float) relativeTime / CLOCKS_PER_SEC;
QGLFunctions::glDisableVertexAttribArray(0);
}
You can create your own two signals
void startPaint() and void endPaint()
Than catch them somwhere(MainWindow maybe) and void startPaint() will start timer, and void endPaint() will stop timer and store value somewhere. Qt class QElapsedTimer should do the job.

Does QTimer keep counting once it's timedout?

I would like to know if a QTimer will keep on counting once it has timed out.
For example, let's say I have a QTimer that times out every 500ms. Let's say when this particular QTimer times out, my program happens to be in some function that I have made (not in the event loop) and it takes 10ms for the program to get from my function, to the event loop. Does that mean that the next time the QTimer times out will be at 1010ms?
If this is the case, is there a way to get around it?
Thanks.
Edit:
When you put a Qtimer with delay d, it will fire a timeout() signal after this period of time is elapsed and as soon as all the events in the window system's event queue have been processed.
So if your program spend whatever time not in the event loop then it is fine. Anyway whether in Qt or not, setting a timeout to t ms really means, wake me up when at least t ms have passed. You cannot guarantee exactitude whatsoever.
ps: If you are worried about few ms then you should be worried about the timing granularity.
I made some test using multiple timers but with timerEvent (QObject::setTimer()).
The thing is, of course if you have multiple timers that interfere at some point (tick exactly in the same time) all your doStuffThatTake10ms code will be 'queued' ... But the absolute precision of timers should remain over time. Here some code to try it out.
#ifndef MULTITIMER_H
#define MULTITIMER_H
#include <QObject>
#include <QTime>
class MultiTimer : public QObject
{
Q_OBJECT
public:
explicit MultiTimer(QObject *parent = 0);
void timerEvent(QTimerEvent *event);
private:
int timerId[4];
int interval[4];
int count[4];
QTime absoluteTimer;
};
#endif // MULTITIMER_H
Implementation .cpp
#include "MultiTimer.h"
#include <QTimerEvent>
#include <QTime>
#include <QDebug>
MultiTimer::MultiTimer(QObject *parent) :
QObject(parent)
{
interval[0] = 500;
interval[1] = 1000;
interval[2] = 1500;
interval[3] = 2000;
for( int i = 0; i < 4; i++)
timerId[i] = startTimer(interval[i]);
for( int i = 0; i < 4; i++)
count[i] = 0;
absoluteTimer.start();
}
void MultiTimer::timerEvent(QTimerEvent *event)
{
int id = -1;
for( int i = 0; i < 4; i++){
if( event->timerId() == timerId[i]){
id = i;
count[id]++;
break;
}
}
if( id != -1) {
qDebug() << "timer" << id
<< "interval" << interval[id]
<< "count" << count[id]
<< "total" << count[id]*interval[id]
<< "reference" << absoluteTimer.elapsed();
usleep(10000);
}
}
To try it out create a = QApllication() and a MultiTimer object and fire a.exec().
Result after 1 minute on linux
timer 1 interval 1000 count 59 total 59000 reference 59010
timer 0 interval 500 count 119 total 59500 reference 59500
timer 0 interval 500 count 120 total 60000 reference 60000
timer 1 interval 1000 count 60 total 60000 reference 60010
timer 3 interval 2000 count 30 total 60000 reference 60021
timer 2 interval 1500 count 40 total 60000 reference 60031
timer 0 interval 500 count 121 total 60500 reference 60500
As you can see the 121th tick of timer 0 is right on time at 60500ms ... but at 60000ms all timers collide creating delayed execution.

How to create a count down time with Qt?

All developer could you show me how to create a count down time with c++ Qt? If you can, you should to show me a source code.
You could use something like that. It calls timeOutSlot every second.
#define TIMEOUT 60
...
QTimer * timer = new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(timeOutSlot()));
timer->start(1000);
...
void timeOutSlot()
{
static int time = TIMEOUT;
time--; // decrement counter
if (time==0) // countdown has finished
{
// timeout
}
else // re-start counter
{
time->start(1000);
}
}

How to provide auto change for a QTimeEdit?

I have a QTimeEdit widget on my dialog and I want to provide some kind of autochange - if the cursor is on minutes section and the time is 04:59, the next click on the arrow up would lead the time to change to 5:00.
How to do that?
I saw some mention of AutoAdvance property but I suppose it's obsolete because I cannot find it in Qt 4.7.
I noticed there is a signal called void timeChanged ( const QTime & time ). You can connect it to a slot and call function void QAbstractSpinBox::stepBy ( int steps ) in the slot function.
EDIT1:
Sorry for the misleading. In fact, we don't really need void timeChanged ( const QTime & time ).
See the code below:
class myTime : public QTimeEdit
{
Q_OBJECT
public:
virtual void stepBy(int steps)
{
if (this->time().minute()==59 && steps>0){
setTime(QTime(time().hour()+1,0,time().second(),time().msec()));
}else if(this->time().minute()==00 && steps<0){
setTime(QTime(time().hour()-1,59,time().second(),time().msec()));
}else{
QTimeEdit::stepBy(steps);
}
}
};
Keep in mind, you need to setWrapping(true) yourself.
I don't know whether it's still interesting, but I found another solution:
class myTime : public QTimeEdit {
Q_OBJECT public:
virtual void stepBy(int steps)
{
long lFactor=1;
if (currentSection()==QDateTimeEdit::MinuteSection)
lFactor=60;
else if (currentSection()==QDateTimeEdit::HourSection)
lFactor=3600;
long lDateTime = (dateTime().toMSecsSinceEpoch()/1000)+(steps*lFactor);
QDateTime dt = QDateTime::fromMSecsSinceEpoch(1000*(qint64)(lDateTime));
setDateTime(dt);
} };
If some one is wondering how to automatically change time (because I did), and needs easy, rather clean solution, here's what I came up with:
class TimeWidget : public QTimeEdit {
Q_OBJECT
public:
void stepBy(int steps) {
//Grab the current time
QTime t = time();
//So we edit the time as in raw milliseconds. Larger type would be better in this case.
//But 32bits is more than enough for day amount of milliseconds.
int raw = (t.hour()*360000 + t.minute()*60000 + t.second() * 1000 + t.msec());
//Let's find out what section time widget is changing
//And edit the raw millisecond data accordingly.
switch(currentSection()) {
case QDateTimeEdit::MSecSection:
raw += steps;
break;
case QDateTimeEdit::SecondSection:
raw += steps*1000;
break;
case QDateTimeEdit::MinuteSection:
raw+= steps*60000;
break;
case QDateTimeEdit::HourSection:
raw += steps*3600000;
break;
}
//Now we just split the "raw" milliseconds into
int hrs = (raw/ 36000000) % 24; //... hours
int mins = (raw/ 60000) % 60; //... minutes
int secs = (raw / 1000) % 60; //... seconds
int mills = raw % 1000; //... milliseconds
//Update & save the current time
t.setHMS(hrs, mins, secs, mills);
setTime(t);
}
};

Resources