I’m trying to make a basic timer, this code seems to print out the number of milliseconds correctly based on the value in duration
But can someone tell me why it prints the output 4 times for each ‘tick’regardless of what the value of duration is, and how to correct it so that it only outputs once on every ‘tick’ set in duration? I’m sure it must be something simple I’m overlooking but I’m still learning the basics of C++ and I can’t see the error.
I’m running it on the iOS “Mobile C” app, but I don’t imagine that that would be what’s causing the problem.
#include <chrono>
#include <iostream>
int main()
{
using namespace std::chrono;
auto start = high_resolution_clock::now();
int duration = 100;
int i = 0;
while (i <= 100)
{
auto now = high_resolution_clock::now();
auto millis = duration_cast<milliseconds>(now - start).count();
if (millis % duration == 0)
{
std::cout << "millis: " << millis << std::endl;
i++;
}
}
}
Since I'm still new here I can't post a comment but the reason you are getting that output 4 times is because that if statement is true 4 times for that one millisecond on your machine like Jesper Juhl was saying. Consider using a bool to make sure it only runs once. Something like
bool hasRun = false;
if (millis % duration == 0)
{
if (!hasRun)
{
std::cout << "millis: " << millis << std::endl;
hasRun = true;
}
}
else
hasRun = false;
Then you would be able to keep you infinite Arduino simulation loop like you mentioned in the comments but only have the statement ring true once per duration.
Related
I made a factoring program that needs to loop as quickly as possible. However, I also want to track the progress with minimal code. To do this, I display the current value of i every second by comparing time_t start - time_t end and an incrementing value marker.
using namespace std; // cause I'm a noob
// logic stuff
int divisor = 0, marker = 0;
int limit = sqrt(num);
for (int i = 1; i <= limit; i++) // odd number = odd factors
{
if (num % i == 0)
{
cout << "\x1b[2K" << "\x1b[1F" << "\x1b[1E"; // clear, up, down
if (i != 1)
cout << "\n";
divisor = num / i;
cout << i << "," << divisor << "\n";
}
end = time(&end); // PROBLEM HERE
if ((end - start) > marker)
{
cout << "\x1b[2K" << "\x1b[1F" << "\x1b[1E"; // clear, up, down
cout << "\t\t\t\t" << i;
marker++;
}
}
Of course, the actual code is much more optimized and uses boost::multiprecision, but I don't think that's the problem. When I remove the line end = time(&end), I see a performance gain of at least 10%. I'm just wondering, how can I track the time (or at least approximate seconds) without unconditionally calling a function every loop? Or is there a faster function?
You observe "When I remove the line end = time(&end), I see a performance gain of at least 10%." I am not surprised, reading time easily is taking inefficient time, compared to doing pure CPU calculations.
I assume hence that the time reading is actually what eats the performance which observe lost when removing the line.
You could use an estimation of the minimum number of iterations your loop does within a second and then only check the time if multiples of (half of) that number have looped.
I.e., if you only want to be aware of time in a resolution of seconds, then you should try to only marginally more often do the time-consuming reading of the time.
I would use a totally different approach where you seperate measurement/display code from the loop completely and even run it on another thread.
Live demo here : https://onlinegdb.com/8nNsGy7EX
#include <iostream>
#include <chrono> // for all things time
#include <future> // for std::async, that allows us to run functions on other threads
void function()
{
const std::size_t max_loop_count{ 500 };
std::atomic<std::size_t> n{ 0ul }; // make access to loopcounter threadsafe
// start another thread that will do the reporting independent of the
// actual work you are doing in your loop.
// for this capture n (loop counter) by reference (so this thread can look at it)
auto future = std::async(std::launch::async,[&n, max_loop_count]
{
while (n < max_loop_count)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "\rprogress = " << (100 * n) / max_loop_count << "%";
}
});
// do not initialize n here again. since we share it with reporting
for (; n < max_loop_count; n++)
{
// do your loops work, just a short sleep now to mimmick actual work
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
// synchronize with reporting thread
future.get();
}
int main()
{
function();
return 0;
}
If you have any questions regarding this example let me know.
I am beginning in C++ and with the "chrono" function, and I'd like to use it to get the speed of a motor.
For that, I have a coding wheel linked to a motor, an optocoupler is used to gather the square signal generated by the coding wheel.
Therefore, my raspberry pi receive a square signal which speed depends on the motor speed.
I used the chrono function to try to calculate the duration of the frequency of the square signal.
I achieved to have the duration of each signal (almost) which is 7ms.
I'd like to simply extract the frequency through the formula 1/F (therefore, 1/0.007 = 142.85).
I've been eating the documentation of the chrono function for a week, and I still don't get it at all...
Apparently, all the answers are here, but I don't understand that, I'm still a beginner in C++ :( https://en.cppreference.com/w/cpp/chrono
This has been REALLY usefull, but limited : https://www.code57.com/cplusplus-programming-beginners-tutorial-utilities-chrono/
If I understand right, the "value" of 7ms is stored in an "object"...
How can I simply get it out of there and put it in a standard variable so I can divide, multiply and do whatever I want with it?
Here is the interresting part of the C++ code :
#include <iostream>
#include <wiringPi.h>
#include <cstdio>
#include <csignal>
#include <ctime>
#include <chrono>
// global flag used to exit from the main loop
bool RUNNING = true;
bool StartTimer = false;
//int timer = 0;
std::chrono::steady_clock::time_point BeginMeasurement; //chrono variable representing the beginning of the measurement of a motor speed
//some more code in here, but nothing exceptionnal, just calling the interruption when needed
//interruption function for counting the motor speed
void RPMCounter(){
using namespace std;
using namespace std::chrono;
if (StartTimer == true){
StartTimer = false;
steady_clock::duration result = steady_clock::now()-BeginMeasurement;
if (duration_cast<milliseconds>(result).count() < 150){
double freq;
//cout.precision(4);
std::cout << "Time = " << duration_cast<milliseconds>(result).count() << " ms" << '\n';
// I would like the next line to work and give me the frequency of the detection...
freq = 1/(duration_cast<milliseconds>(result).count()/1000);
std::cout << "Frequency = " << freq << " Hz" << '\n';
}
}
else{
BeginMeasurement = steady_clock::now();
StartTimer = true;
}
}
Here is the result in my command prompt :
the value of 7ms increases because I stopped the motor, therefore, it was turning slower until stopping ;)
Edit :
Thanks to Howard Hinnant and Ted Lyngmo, My code now looks like this :
void RPMCounter(){
using namespace std;
using namespace std::chrono;
if (StartTimer == true){
StartTimer = false;
duration<double> result = steady_clock::now() - BeginMeasurement;
if (result < milliseconds{150}){
double freq;//= 1s / result;
//cout.precision(4);
std::cout << "Time = " << duration_cast<milliseconds>(result).count() << " ms" << '\n';
freq = (1.0/(duration<double>{result}.count()/1000))/1000;
std::cout << "Frequency = " << freq << " Hz" << '\n';
}
}
else{
BeginMeasurement = steady_clock::now();
StartTimer = true;
}
}
and it seems to give me a correct frequency.
As i'm a beginner, I'll surely understand all that better in a while and improve it :)
(basically, I'm not exactly sure of what I wrote mean... like the "::" and other ways of :)
The rest of my coding should be more basic and allow me to learn all the tweaks of C++
if (duration_cast<milliseconds>(result).count() < 150){
You can simplify this with:
if (result < 150ms)
Or if you're in C++11:
if (result < milliseconds{150})
The advantage is that you don't have to truncate result to a courser precision, and the code is just easier to read.
freq = 1/(duration_cast<milliseconds>(result).count()/1000);
Instead:
using dsec = duration<double>; // define a double-based second
auto freq = 1/dsec{result}.count();
This could also be written:
auto freq = 1/duration<double>{result}.count();
In any event, this converts result straight to double-based seconds, and inverts that value using floating point arithmetic. The original code uses integral division resulting in an integral result that is always rounding down to 0. I.e. 1/10 == 0, whereas 1/10. == 0.1.
I'd make the result a double based duration:
auto BeginMeasurement = std::chrono::steady_clock::now();
// some work
// a double based duration
std::chrono::duration<double> result = std::chrono::steady_clock::now() - BeginMeasurement;
You can then divide the duration 1s with result to get the frequency:
using namespace std::chrono_literals;
double freq = 1s / result;
std::cout << freq << " Hz\n";
Howard Hinnant pointed out that from C++14 you can make it even easier for youself by changing the dividend from an integer based duration, 1s, to a double based duration, 1.0s, and let result be deduced using auto:
auto result = std::chrono::steady_clock::now() - BeginMeasurement;
double freq = 1.0s / result;
Demo
What I want to do, my project:
I want to make a program that waits 0.5 seconds, for example, does something, let's say cout << "Hello World", once and then again the same for about 10 times(this is a test for another program), but without sleep, sleep_for, sleep or anything similar BCS I don't want the processor to actually sleep, BCS at that time the processor does not just wait, it does nothing for that time, for these 0.5 seconds it does nothing and I don't want that, and the main reason is BCS it also doesn't take input.
What I tried:
What I tried was to keep two points in time(time_point start,end), duration_cast their difference (end - start) in a for loop ((int i = 0;i < 10;i++)), and if their difference was 500 milliseconds, then, cout << "Hello World\n";.
My code looked something like this:
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
using namespace chrono;
int main()
{
time_point<steady_clock> t = steady_clock::now():
for (int i = 0; i < 10;)
{
duration<double> d = steady_clock::now() - t;
uint32_t a = duration_cast<milliseconds>(d).count();
if (a >= 500)
{
cout << a << " Hello World!" << endl;
t = steady_clock::now();
i++;
}
}
return 0;
}
My problem:
It overflows, most of the time, I don't know what exactly overflows, but a appears to be sometimes 6??? others 47??? (? = some digit)
I tried many things, I ended up to something like this:
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
using namespace chrono;
int main()
{
time_point<high_resolution_clock> t = high_resolution_clock::now();
for (int i = 0; i< 10;)
{
duration<double,ratio<1,1000000>> d = high_resolution_clock::now() - t;
uint32_t a = duration_cast<microseconds>(d).count();
if (d >= microseconds(500000) )
{
cout << a << " Hello World!" << endl;
i++;
t = high_resolution_clock::now();
}
}
return 0;
}
It didn't really solve the problem, but the max value appears is `~1500(1500000 in microseconds) and when it happens it takes longer to print the message, I don't know if its still overflow, to be honest, but...
Question
Anyway, do you have any suggestions about how to stop the overflow or a completely different way to achieve what I want, even if you don't, thanks for spending time to read my question, I hope to express someone else's question if there someone who has the same question as me.
Not sure if this is what you're looking for or not. But if not, maybe we can build on this to figure out what you want:
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
auto t = steady_clock::now();
for (int i = 0; i < 10; ++i)
{
auto t1 = t + 500ms;
while (steady_clock::now() < t1)
;
cout << duration<double>(t1-t).count() << " Hello World!" << endl;
t = t1;
}
}
The code sets a time_point for 500ms in the future, and then enters a busy loop until that future time_point is now.
Abstract:
I wrote a short program dealing with the Chrono library in C++ for experimentation purposes. I want the CPU to count as high as it can within one second, display what it counted to, then repeat the process within an infinite loop.
Current Code:
#include <iostream>
#include <chrono>
int counter()
{
int num = 0;
auto startTime = std::chrono::system_clock::now();
while (true)
{
num++;
auto currentTime = std::chrono::system_clock::now();
if (std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime).count() == 1)
return num;
}
}
int main()
{
while(true)
std::cout << "You've counted to " << counter() << "in one second!";
return 0;
}
Problem:
The conditional statement in my program:
if (std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime).count() == 1)
isn't being triggered because the casted value of currentTime - startTime never equals nor rises above one. This can be demonstrated by replacing the operator '==' with '<', which outputs an incorrect result, as opposed to outputting nothing at all. I don't understand why the condition isn't being met; if this program is gathering time from the system clock at one point, then repeatedly comparing it to the current time, shouldn't the integer value of the difference equal one at some point?
You're hitting a cout issue, not a chrono issue. The problem is that you're printing with cout which doesn't flush if it doesn't feel like it.
cerr will flush on newline. Change to cerr and add a \n and you'll get what you expect.
std::cerr << "You've counted to " << counter() << "in one second!\n";
I am trying to create a timer where it begins with a certain value and ends with another value like.
int pktctr = (unsigned char)unpkt[0];
if(pktctr == 2)
{
cout << "timer-begin" << endl;
//start timer here
}
if(pktctr == 255)
{
cout << "timer-end" << endl;
//stop timer here
//timer display total time then reset.
}
cout << "displays total time it took from 1 to 255 here" << endl;
Any idea on how to achieve this?
void WINAPI MyUCPackets(char* unpkt, int packetlen, int iR, int arg)
{
int pktctr = (unsigned char)unpkt[0];
if(pktctr == 2)
{
cout << "timer-begin" << endl;
}
if(pktctr == 255)
{
cout << "timer-end" << endl;
}
return MyUC2Packets(unpkt,packetlen,iR,arg);
}
Everytime this function is called unpkt starts from 2 then reaches max of 255 then goes back to 1. And I want to compute how long it took for every revolution?
This will happen alot of times. But I just wanted to check how many seconds it took for this to happen because it won't be the same everytime.
Note: This is done with MSDetours 3.0...
I'll assume you're using Windows (from the WINAPI in the code) in which case you can use GetTickCount:
/* or you could have this elsewhere, e.g. as a class member or
* in global scope (yuck!) As it stands, this isn't thread safe!
*/
static DWORD dwStartTicks = 0;
int pktctr = (unsigned char)unpkt[0];
if(pktctr == 2)
{
cout << "timer-begin" << endl;
dwStartTicks = GetTickCount();
}
if(pktctr == 255)
{
cout << "timer-end" << endl;
DWORD dwDuration = GetTickCount() - dwStartTicks;
/* use dwDuration - it's in milliseconds, so divide by 1000 to get
* seconds if you so desire.
*/
}
Things to watch out for: overflow of GetTickCount is possible (it resets to 0 approximately every 47 days, so it's possible that if you start your timer close to the rollover time, it will finish after the rollover). You can solve this in two ways, either use GetTickCount64 or simply notice when dwStartTicks > GetTickCount and if so, calculate how many milliseconds were from dwStartTicks until the rollover, and how many millseconds from 0 to the result of GetTickCount() and add those numbers together (bonus points if you can do this in a more clever way).
Alternatively, you can use the clock function. You can find out more on that, including an example of how to use it at http://msdn.microsoft.com/en-us/library/4e2ess30(v=vs.71).aspx and it should be fairly easy to adapt and integrate into your code.
Finally, if you're interested in a more "standard" solution, you can use the <chrono> stuff from the C++ standard library. Check out http://en.cppreference.com/w/cpp/chrono for an example.
If you want to use the Windows-API use GetSystemTime(). Provide a struct SYSTEMTIME, initialize it properly and pass it to GetSystemTime():
#include <Windows.h>
...
SYSTEMTIME sysTime;
GetFileTime(&sysTime);
// use sysTime and create differences
Look here for GetSystemTime() there is a link for SYSTEMTIME there, too.
I think boost timer is the best solution for you.
You can check the elapsed time like this:
#include <boost/timer.hpp>
int main() {
boost::timer t; // start timing
...
double elapsed_time = t.elapsed();
...
}