I need to pass from microseconds (saved inside a unsigned long long int variable) to its representation as hours, minutes, seconds, milliseconds, that is:
from 47072349659 to 13:04:32.350
I found this conversion from milliseconds, but I don't seem to manage to make it work in my case. Maybe the problem is that the number is too long to be stored in certain variable type? I'm using unsigned long long int for input time and tried int, long, unsigned long long int for outputs.
Here is my C++ code:
unsigned long long int timestamp;
long milliseconds = (long) (timestamp / 1000000) % 1000;
long seconds = (long) ((timestamp / (1000)) % 60);
long minutes = (long) ((timestamp / (60000)) % 60);
long hours = (long) ((timestamp / (3600000)) % 24);
I think your mistake is in your deviders :
long milliseconds = (long) (timestamp / 1000) % 1000;
long seconds = (((long) (timestamp / 1000) - milliseconds)/1000)%60 ;
long minutes = (((((long) (timestamp / 1000) - milliseconds)/1000) - seconds)/60) %60
long hours = ((((((long) (timestamp / 1000) - milliseconds)/1000) - seconds)/60) - minutes)/60
Related
I have two similar codes below.
1st code:
unsigned long size = 256*1024*1024;
unsigned long stride = 256;
void *array = (void*)malloc(size);
for (unsigned long off = 0; off < size; off+=stride) {
*(unsigned int*)(array+off) = off+stride;
}
*(unsigned int*)(array+off)=0;
int i=10000000;
struct timeval start, end;
gettimeofday(&start, NULL);
while (i>=1) {
offset = *(unsigned int*)(array+off);
i--;
}
gettimeofday(&end, NULL);
*(volatile unsigned int*)(array+offset);
printf("%.2f\n", (end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec));
2nd code:
unsigned long size = 256*1024*1024;
unsigned long stride = 256;
void *array = (void*)malloc(size);
for (unsigned long off = 0; off < size; off+=stride) {
*(unsigned int*)(array+off) = off+stride;
}
*(unsigned int*)(array+off)=0;
int i=10000000;
struct timeval start, end;
gettimeofday(&start, NULL);
#define ONE offset = *(unsigned int*)(array+off);
#define FIVE ONE ONE ONE ONE ONE
#define TEN FIVE FIVE
#define FIFTY TEN TEN TEN TEN TEN
#define HUNDRED FIFTY FIFTY
while (i>=1000) {
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
HUNDRED
i-=1000;
}
gettimeofday(&end, NULL);
*(volatile unsigned int*)(array+offset);
printf("%.2f\n", (end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec));
Question
The only difference between two codes is "while loop."
They both measure the elapsed time for while loop.
The first code makes a result of 779,851,000 ns and the second code makes a result of 1,624,344,000 ns. (2.1 times larger)
I thought this difference comes from L1-i cache misses, so I measured L1-i cache misses with perf.
However, the L1-i cache miss of the first code is 34,541 and the L1-i cache miss of the second code is 43,078. (1.2 times larger)
This result cannot completely explain the difference in elapsed times for while loop.
What makes the big difference between elapsed times of two codes?
Is there anything that I miss?
I am unable to send serial output data to Ms.Excel sheet.
I am using Proteus 8 professional software, Arduino 1.8.5 IDE with windos 7 OS in a 32bit system. Could anyone please guide me to send the data.
Here is my Ardunio code:
int incomingByte = 0;
unsigned long time;
unsigned long day = 86400000; // 86400000 milliseconds in a day
unsigned long hour = 3600000; // 3600000 milliseconds in an hour
unsigned long minute = 60000; // 60000 milliseconds in a minute
unsigned long second = 1000; // 1000 milliseconds in a second
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
if (Serial.available() > 0)
{
incomingByte = Serial.read(); // read the incoming byte:
Serial.print("Time: ");
time = millis();
int days = time / day ; //number of days
int hours = (time % day) / hour; //the remainder from
days division (in milliseconds) divided by hours, this gives the full hours
int minutes = ((time % day) % hour) / minute ; //and so on...
int seconds = (((time % day) % hour) % minute) / second;
Serial.print(days,DEC);
Serial.println(hours);
Serial.println(minutes);
Serial.println(seconds);
delay(1000);
}
}
I am trying to speed up a single program by using prefetches. The purpose of my program is just for test. Here is what it does:
It uses two int buffers of the same size
It reads one-by-one all the values of the first buffer
It reads the value at the index in the second buffer
It sums all the values taken from the second buffer
It does all the previous steps for bigger and bigger
At the end, I print the number of voluntary and involuntary CPU
In the very first time, values in the first buffers contains the values of its index (cf. function createIndexBuffer in the code just below) .
It will be more clear in the code of my program:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#define BUFFER_SIZE ((unsigned long) 4096 * 100000)
unsigned int randomUint()
{
int value = rand() % UINT_MAX;
return value;
}
unsigned int * createValueBuffer()
{
unsigned int * valueBuffer = (unsigned int *) malloc(BUFFER_SIZE * sizeof(unsigned int));
for (unsigned long i = 0 ; i < BUFFER_SIZE ; i++)
{
valueBuffer[i] = randomUint();
}
return (valueBuffer);
}
unsigned int * createIndexBuffer()
{
unsigned int * indexBuffer = (unsigned int *) malloc(BUFFER_SIZE * sizeof(unsigned int));
for (unsigned long i = 0 ; i < BUFFER_SIZE ; i++)
{
indexBuffer[i] = i;
}
return (indexBuffer);
}
unsigned long long computeSum(unsigned int * indexBuffer, unsigned int * valueBuffer)
{
unsigned long long sum = 0;
for (unsigned int i = 0 ; i < BUFFER_SIZE ; i++)
{
unsigned int index = indexBuffer[i];
sum += valueBuffer[index];
}
return (sum);
}
unsigned int computeTimeInMicroSeconds()
{
unsigned int * valueBuffer = createValueBuffer();
unsigned int * indexBuffer = createIndexBuffer();
struct timeval startTime, endTime;
gettimeofday(&startTime, NULL);
unsigned long long sum = computeSum(indexBuffer, valueBuffer);
gettimeofday(&endTime, NULL);
printf("Sum = %llu\n", sum);
free(indexBuffer);
free(valueBuffer);
return ((endTime.tv_sec - startTime.tv_sec) * 1000 * 1000) + (endTime.tv_usec - startTime.tv_usec);
}
int main()
{
printf("sizeof buffers = %ldMb\n", BUFFER_SIZE * sizeof(unsigned int) / (1024 * 1024));
unsigned int timeInMicroSeconds = computeTimeInMicroSeconds();
printf("Time: %u micro-seconds = %.3f seconds\n", timeInMicroSeconds, (double) timeInMicroSeconds / (1000 * 1000));
}
If I launch it, I get the following output:
$ gcc TestPrefetch.c -O3 -o TestPrefetch && ./TestPrefetch
sizeof buffers = 1562Mb
Sum = 439813150288855829
Time: 201172 micro-seconds = 0.201 seconds
Quick and fast!!!
According to my knowledge (I may be wrong), one of the reason for having such a fast program is that, as I access my two buffers sequentially, data can be prefetched in the CPU cache.
We can make it more complex in order that data is (almost) prefeched in CPU cache. For example, we can just change the createIndexBuffer function in:
unsigned int * createIndexBuffer()
{
unsigned int * indexBuffer = (unsigned int *) malloc(BUFFER_SIZE * sizeof(unsigned int));
for (unsigned long i = 0 ; i < BUFFER_SIZE ; i++)
{
indexBuffer[i] = rand() % BUFFER_SIZE;
}
return (indexBuffer);
}
Let's try the program once again:
$ gcc TestPrefetch.c -O3 -o TestPrefetch && ./TestPrefetch
sizeof buffers = 1562Mb
Sum = 439835307963131237
Time: 3730387 micro-seconds = 3.730 seconds
More than 18 times slower!!!
We now arrive to my problem. Given the new createIndexBuffer function, I would like to speed up computeSum function using prefetch
unsigned long long computeSum(unsigned int * indexBuffer, unsigned int * valueBuffer)
{
unsigned long long sum = 0;
for (unsigned int i = 0 ; i < BUFFER_SIZE ; i++)
{
__builtin_prefetch((char *) &indexBuffer[i + 1], 0, 0);
unsigned int index = indexBuffer[i];
sum += valueBuffer[index];
}
return (sum);
}
of course I also have to change my createIndexBuffer in order it allocates a buffer having one more element
I relaunch my program: not better! As prefetch may be slower than one "for" loop iteration, I may prefetch not one element before but two elements before
__builtin_prefetch((char *) &indexBuffer[i + 2], 0, 0);
not better! two loops iterations? not better? Three? **I tried it until 50 (!!!) but I cannot enhance the performance of my function computeSum.
Can I would like help to understand why
Thank you very much for your help
I believe that above code is automatically optimized by CPU without any further space for manual optimization.
1. Main problem is that indexBuffer is sequentially accessed. Hardware prefetcher senses it and prefetches further values automatically, without need to call prefetch manually. So, during iteration #i, values indexBuffer[i+1], indexBuffer[i+2],... are already in cache. (By the way, there is no need to add artificial element to the end of array: memory access errors are silently ignored by prefetch instructions).
What you really need to do is to prefetch valueBuffer instead:
__builtin_prefetch((char *) &valueBuffer[indexBuffer[i + 1]], 0, 0);
2. But adding above line of code won't help either in such simple scenario. Cost of accessing memory is hundreds of cycles, while add instruction is ~1 cycle. Your code already spends 99% of time in memory accesses. Adding manual prefetch will make it this one cycle faster and no better.
Manual prefetch would really work well if your math were much more heavy (try it), like using an expression with large number of non-optimized out divisions (20-30 cycles each) or calling some math function (log, sin).
3. But even this doesn't guarantee to help. Dependency between loop iterations is very weak, it is only via sum variable. This allows CPU to execute instructions speculatively: it may start fetching valueBuffer[i+1] concurrently while still executing math for valueBuffer[i].
Prefetch fetches normally a full cache line. This is typically 64 bytes. So the random example fetches always 64 bytes for a 4 byte int. 16 times the data you actually need which fits very well with the slow down by a factor of 18. So the code is simply limited by memory throughput and not latency.
Sorry. What I gave you was not the correct version of my code. The correct version is, what you said:
__builtin_prefetch((char *) &valueBuffer[indexBuffer[i + prefetchStep]], 0, 0);
However, even with the right version, it is unfortunately not better
Then I adapted my program to try your suggestion using the sin function.
My adapted program is the following one:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <math.h>
#define BUFFER_SIZE ((unsigned long) 4096 * 50000)
unsigned int randomUint()
{
int value = rand() % UINT_MAX;
return value;
}
unsigned int * createValueBuffer()
{
unsigned int * valueBuffer = (unsigned int *) malloc(BUFFER_SIZE * sizeof(unsigned int));
for (unsigned long i = 0 ; i < BUFFER_SIZE ; i++)
{
valueBuffer[i] = randomUint();
}
return (valueBuffer);
}
unsigned int * createIndexBuffer(unsigned short prefetchStep)
{
unsigned int * indexBuffer = (unsigned int *) malloc((BUFFER_SIZE + prefetchStep) * sizeof(unsigned int));
for (unsigned long i = 0 ; i < BUFFER_SIZE ; i++)
{
indexBuffer[i] = rand() % BUFFER_SIZE;
}
return (indexBuffer);
}
double computeSum(unsigned int * indexBuffer, unsigned int * valueBuffer, unsigned short prefetchStep)
{
double sum = 0;
for (unsigned int i = 0 ; i < BUFFER_SIZE ; i++)
{
__builtin_prefetch((char *) &valueBuffer[indexBuffer[i + prefetchStep]], 0, 0);
unsigned int index = indexBuffer[i];
sum += sin(valueBuffer[index]);
}
return (sum);
}
unsigned int computeTimeInMicroSeconds(unsigned short prefetchStep)
{
unsigned int * valueBuffer = createValueBuffer();
unsigned int * indexBuffer = createIndexBuffer(prefetchStep);
struct timeval startTime, endTime;
gettimeofday(&startTime, NULL);
double sum = computeSum(indexBuffer, valueBuffer, prefetchStep);
gettimeofday(&endTime, NULL);
printf("prefetchStep = %d, Sum = %f - ", prefetchStep, sum);
free(indexBuffer);
free(valueBuffer);
return ((endTime.tv_sec - startTime.tv_sec) * 1000 * 1000) + (endTime.tv_usec - startTime.tv_usec);
}
int main()
{
printf("sizeof buffers = %ldMb\n", BUFFER_SIZE * sizeof(unsigned int) / (1024 * 1024));
for (unsigned short prefetchStep = 0 ; prefetchStep < 250 ; prefetchStep++)
{
unsigned int timeInMicroSeconds = computeTimeInMicroSeconds(prefetchStep);
printf("Time: %u micro-seconds = %.3f seconds\n", timeInMicroSeconds, (double) timeInMicroSeconds / (1000 * 1000));
}
}
The output is:
$ gcc TestPrefetch.c -O3 -o TestPrefetch -lm && taskset -c 7 ./TestPrefetch
sizeof buffers = 781Mb
prefetchStep = 0, Sum = -1107.523504 - Time: 20895326 micro-seconds = 20.895 seconds
prefetchStep = 1, Sum = 13456.262424 - Time: 12706720 micro-seconds = 12.707 seconds
prefetchStep = 2, Sum = -20179.289469 - Time: 12136174 micro-seconds = 12.136 seconds
prefetchStep = 3, Sum = 12068.302534 - Time: 11233803 micro-seconds = 11.234 seconds
prefetchStep = 4, Sum = 21071.238160 - Time: 10855348 micro-seconds = 10.855 seconds
prefetchStep = 5, Sum = -22648.280105 - Time: 10517861 micro-seconds = 10.518 seconds
prefetchStep = 6, Sum = 22665.381676 - Time: 9205809 micro-seconds = 9.206 seconds
prefetchStep = 7, Sum = 2461.741268 - Time: 11391088 micro-seconds = 11.391 seconds
...
So here, it works better! Honestly, I was almost sure that it will not be better because the math function cost is higher compared to the memory access.
If anyone could give me more information about why it is better now, I would appreciate it
Thank you very much
I've seen lots of questions about high precision timers in windows, but what I really need is something that gives me the clock time in windows that's more accurate than the 10-15ms granularity GetLocalTime() offers.
I couldn't find any existing and simple solution so I came up with one of my own, not completely flushed out, but the basic idea works until midnight. Sharing it here so it can be helpful to others.
Store an anchor time when the program starts and use timeGetTime() to get the system uptime in ms (which is granular to less than 1 ms) and adjust the anchortime accordingly.
Code is in the answer.
First time you run it, it gets the time and the tickcount so they're in sync and we have something to measure by. The init section isn't threadsafe and it doesn't wrap over midnight, but that's easily added by following the carry form below....
// this solution is limited to 49+ days of uptime
int timeinitted = 0;
SYSTEMTIME anchortime;
DWORD anchorticks;
void GetAccurateTime(SYSTEMTIME *lt)
{
if (timeinitted == 0)
{ // obviously this init section isn't threadsafe.
// get an anchor time to sync up with system ticks.
GetLocalTime(&anchortime);
anchorticks = timeGetTime();
timeinitted = 1;
}
DWORD now = timeGetTime();
DWORD flyby = now - anchorticks;
// now add flyby to anchortime
memcpy (lt, &anchortime, sizeof(anchortime));
// you can't do the math IN the SYSTEMTIME because everything in it is a WORD (16 bits)
DWORD ms = lt->wMilliseconds + flyby;
DWORD carry = ms / 1000;
lt->wMilliseconds = ms % 1000;
if (carry > 0)
{
DWORD s = lt->wSecond + carry;
carry = s / 60;
lt->wSecond = s % 60;
if (carry > 0)
{
DWORD m = lt->wMinute + carry;
carry = m / 60;
lt->wMinute = m % 60;
if (carry > 0) // won't wrap day correctly.
lt->wHour = (((DWORD)lt->wHour + carry)) % 24;
}
// add day and month and year here if you're so inspired, but remember the 49 day limit
}
}
I have a time value represented in SYSTEMTIME, i want to add/subtract 1 hour from it and get the newly obtained SYSTEMTIME. I want the conversion should take care of the date change on addition/subtraction or month change or e1 year change .
Can someone help me with this if there is some windows api which does arithmetic on SYSTEMTIME
If you're using C# (or VB.NET, or ASP.NET) you can use
DateTime dt = DateTime.Now.AddHours(1);
You can use negative numbers to subtract:
DateTime dt = DateTime.Now.AddHours(-1);
EDITED:
I extract an asnwer from this post
They suggest converting SYSTEMTIME to FILETIME, which is a number of
ticks since an epoch. You can then add the required number of 'ticks'
(i.e. 100ns intervals) to indicate your time, and convert back to
SYSTEMTIME.
The ULARGE_INTEGER struct is a union with a QuadPart member, which is
a 64bit number, that can be directly added to (on recent hardware).
SYSTEMTIME add( SYSTEMTIME s, double seconds ) {
FILETIME f;
SystemTimeToFileTime( &s, &f );
ULARGE_INTEGER u ;
memcpy( &u , &f , sizeof( u ) );
const double c_dSecondsPer100nsInterval = 100. * 1.E-9;
u.QuadPart += seconds / c_dSecondsPer100nsInterval;
memcpy( &f, &u, sizeof( f ) );
FileTimeToSystemTime( &f, &s );
return s;
}
If you want to add an hour use SYSTEMTIME s2 = add(s1, 60*60)
To add signed seconds (forward or backward in time) in C++:
const double clfSecondsPer100ns = 100. * 1.E-9;
void iAddSecondsToSystemTime(SYSTEMTIME* timeIn, SYSTEMTIME* timeOut, double tfSeconds)
{
union {
ULARGE_INTEGER li;
FILETIME ft;
};
// Convert timeIn to filetime
SystemTimeToFileTime(timeIn, &ft);
// Add in the seconds
li.QuadPart += tfSeconds / clfSecondsPer100ns;
// Convert back to systemtime
FileTimeToSystemTime(&ft, timeOut);
}
#include <stdio.h>
#include <windows.h>
#define NSEC 60*60
main()
{
SYSTEMTIME st;
FILETIME ft;
// Get local time from system
GetLocalTime(&st);
printf("%02d/%02d/%04d %02d:%02d:%02d\n",
st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
// Convert to filetime
SystemTimeToFileTime(&st,&ft);
// Add NSEC seconds
((ULARGE_INTEGER *)&ft)->QuadPart +=(NSEC*10000000LLU);
// Convert back to systemtime
FileTimeToSystemTime(&ft,&st);
printf("%02d/%02d/%04d %02d:%02d:%02d\n",
st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
}