Porting clock_gettime to windows
You can implement a clock_gettime() replacement for windows as follows:
LARGE_INTEGER
getFILETIMEoffset()
{
SYSTEMTIME s;
FILETIME f;
LARGE_INTEGER t;
s.wYear = 1970;
s.wMonth = 1;
s.wDay = 1;
s.wHour = 0;
s.wMinute = 0;
s.wSecond = 0;
s.wMilliseconds = 0;
SystemTimeToFileTime(&s, &f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
return (t);
}
int
clock_gettime(int X, struct timeval *tv)
{
LARGE_INTEGER t;
FILETIME f;
double microseconds;
static LARGE_INTEGER offset;
static double frequencyToMicroseconds;
static int initialized = 0;
static BOOL usePerformanceCounter = 0;
if (!initialized) {
LARGE_INTEGER performanceFrequency;
initialized = 1;
usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
if (usePerformanceCounter) {
QueryPerformanceCounter(&offset);
frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
} else {
offset = getFILETIMEoffset();
frequencyToMicroseconds = 10.;
}
}
if (usePerformanceCounter) QueryPerformanceCounter(&t);
else {
GetSystemTimeAsFileTime(&f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
}
t.QuadPart -= offset.QuadPart;
microseconds = (double)t.QuadPart / frequencyToMicroseconds;
t.QuadPart = microseconds;
tv->tv_sec = t.QuadPart / 1000000;
tv->tv_usec = t.QuadPart % 1000000;
return (0);
}
clock_gettime: identifier not found in Visual Studio in Windows 10
Function clock_gettime() is defined by POSIX. Windows is not POSIX compliant.
Here's a link to old post of porting clock_gettime() to Windows.
For Windows I would use std::chrono library.
Simple example is :
#include <chrono>
auto start = std::chrono::high_resolution_clock::now();
func();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> duration = end - start;
printf("Duration : %f", duration.count());
Is clock_gettime() correctly implemented in MinGW GCC 8.2.0?
That loop should get optimized out to nothing at all, so with a low resolution clock (resolution is not necessarily individual nanoseconds; it may advance in much larger units which clock_getres
should be able to tell you) 0 is a plausible result. But you have a few other bugs in your code like mixing CLOCK_THREAD_CPUTIME_ID
with CLOCK_PROCESS_CPUTIME_ID
and not checking the return value of clock_gettime
(it might be telling you these clocks aren't supported).
Porting to windows sockets
You need to initialize it first before making any socket call.
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
timespec equivalent for windows
See, for example, How to realise long-term high-resolution timing on windows using C++? and C++ Timer function to provide time in nano seconds.
I have done some testing with Cygwin under Windows XP: on my machine, the granularity of gettimeofday() is about 15 msecs (~1/64 secs). Which is quite coarse. And so is the granularity of:
* clock_t clock(void) (divisor CLOCKS_PER_SEC)
* clock_t times(struct tms *) (divisor sysconf(_SC_CLK_TCK))
Both divisors are 1000 (POSIX may have 1000000 for first).
Also, clock_getres(CLOCK_REALTIME,...) returns 15 msecs, so clock_gettime() is unlikely to help. And CLOCK_MONOTONIC and CLOCK_PROCESS_CPUTIME_ID don't work.
Other possibilites for Windows might be RDTSC; see the Wikipedia article. And HPET, which isn't available with Windows XP.
Also note in Linux, clock() is the process time, while in Windows it is the wall time.
So some sample code, both for standard Unix, and for CYGWIN code running under Windows, which gives a granularity of about 50 microsecs (on my machine). The return value is in seconds, and gives the number of seconds elapsed since the function was first called. (I belatedly realized this was in an answer I gave over a year ago).
#ifndef __CYGWIN32__
double RealElapsedTime(void) { // returns 0 seconds first time called
static struct timeval t0;
struct timeval tv;
gettimeofday(&tv, 0);
if (!t0.tv_sec)
t0 = tv;
return tv.tv_sec - t0.tv_sec + (tv.tv_usec - t0.tv_usec) / 1000000.;
}
#else
#include <windows.h>
double RealElapsedTime(void) { // granularity about 50 microsecs on my machine
static LARGE_INTEGER freq, start;
LARGE_INTEGER count;
if (!QueryPerformanceCounter(&count))
FatalError("QueryPerformanceCounter");
if (!freq.QuadPart) { // one time initialization
if (!QueryPerformanceFrequency(&freq))
FatalError("QueryPerformanceFrequency");
start = count;
}
return (double)(count.QuadPart - start.QuadPart) / freq.QuadPart;
}
#endif
How do I port code calling QueryPerformanceFrequency to Rust?
The direct solution to accessing Windows APIs is to use the winapi
crate. In this case, call QueryPerformanceFrequency
:
use std::mem;
use winapi::um::profileapi::QueryPerformanceFrequency;
fn freq() -> u64 {
unsafe {
let mut freq = mem::zeroed();
QueryPerformanceFrequency(&mut freq);
*freq.QuadPart() as u64
}
}
fn main() {
println!("Hello, world!");
}
[dependencies]
winapi = { version = "0.3.8", features = ["profileapi"] }
hi-resolution MONOTONIC timer
I would use Instant
as a monotonic timer and assume it's high-enough precision until proven otherwise.
Related Topics
How to Monitor a Folder with All Subfolders and Files Inside
Gmon.Out Is Not Written After Compiling with Gcc -Pg -G
What Exif Lib How to Use from a Qt Program (On Embedded Linux)
How to Avoid Multiple Definition Linking Error
Find Argc and Argv from a Library
Get Address Family from Socket. Linux
How to an Share Address Mapping Between Two Unrelated Processes on Linux
Statically Linking System Libraries, Libc, Pthreads, to Aid in Debugging
Sending an Email from a C/C++ Program in Linux
Using Hardware Performance Counters in Linux
Execute a Process from Memory Within Another Process
How to Switch Between Blas Libraries Without Recompiling Program
Changing the Current Directory in Linux Using C++
How to Read Linux File Permission Programmatically in C/C++