annotate dynamin/core/environment.d @ 103:73060bc3f004

Change license to Boost 1.0 and MPL 2.0.
author Jordan Miner <jminer7@gmail.com>
date Tue, 15 May 2012 22:06:02 -0500
parents aa4efef0f0b1
children acdbb30fee7e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
2 /*
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 0
diff changeset
3 * Copyright Jordan Miner
0
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
4 *
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 0
diff changeset
5 * Distributed under the Boost Software License, Version 1.0.
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 0
diff changeset
6 * (See accompanying file BOOST_LICENSE.txt or copy at
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 0
diff changeset
7 * http://www.boost.org/LICENSE_1_0.txt)
0
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
8 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
9 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
10
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
11 module dynamin.core.environment;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
12
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
13 import dynamin.all_core;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
14 import dynamin.core_backend;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
15
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
16 /**
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
17 * Contains static methods to access information about the computer the
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
18 * application is running on.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
19 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
20 static class Environment {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
21 static:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
22 private:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
23 mixin EnvironmentBackend;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
24 public:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
25 /**
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
26 * Returns the time in milliseconds since the program was started.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
27 * On Windows XP, this time is updated every millisecond.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
28 * On Linux, this time is usually updated every millisecond, but
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
29 * occasionally may take 5 to 10 milliseconds.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
30 * This is the author's dream time function because
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
31 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
32 * $(OL
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
33 * $(LI It is accurate to 1 millisecond.)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
34 * $(LI It works correctly on multiple core computers.)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
35 * $(LI It is unaffected by changes to the system time.)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
36 * $(LI It never wraps to zero.)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
37 * )
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
38 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
39 * On my 1.3 GHz celeron, this function can be called about 480 times
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
40 * in one millisecond under Windows and about 380 times in one millisecond
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
41 * under Linux.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
42 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
43 * TODO: make sure it works with multiple cores, although I'm sure it does
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
44 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
45 long runningTime() {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
46 return backend_runningTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
47 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
48 /**
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
49 * Returns the system time in milliseconds since January 1, 1970 UTC.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
50 * On Windows XP, this time is only updated every 15.625 milliseconds.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
51 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
52 * On my 1.3 GHz celeron, this function can be called about 12,000 times
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
53 * in one millisecond under Windows and about 460 times in one millisecond
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
54 * under Linux.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
55 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
56 long systemTime() {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
57 return backend_systemTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
58 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
59 /**
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
60 * Gets the number of logical processors on this computer. A logical
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
61 * processor can either be a different physical processor or simply
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
62 * another core in the same processor. Even a single core hyper-threaded
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
63 * processor is considered to have two logical processors.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
64 * Returns: the number of logical processors
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
65 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
66 int processorCount() {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
67 return backend_processorCount;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
68 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
69 /**
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
70 * The number returned by this method can be used to measure the
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
71 * time between two calls. This method uses the highest resolution
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
72 * timer available.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
73 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
74 * On my 1.3 GHz celeron, this function can be called about 500 times
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
75 * in one millisecond under Windows.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
76 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
77 * Returns: the current time in milliseconds
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
78 *
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
79 * Note: Under Windows, this is implemented using QueryPerformanceCounter().
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
80 * QueryPerformanceCounter() gets the time counter from the processor.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
81 * On processors with multiple cores (such as an Althon X2 or a Core 2 Duo),
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
82 * the time counter for each core may be a few milliseconds different.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
83 * (Microsoft's documentation says this is due to bugs in the BIOS or HAL.)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
84 * Since QueryPerformanceCounter() can get the time from either core,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
85 * the time between two calls made within the same millisecond can be off.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
86 * For example, on my Althon X2 computer, the difference between cores
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
87 * is usually 60 ms. If two calls to QueryPerformanceCounter() are made
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
88 * in the same millisecond, there is a possiblity that the second one
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
89 * will return a time 60 ms smaller than the first.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
90 * Under Linux, this is implemented using gettimeofday(), which has no
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
91 * problems with multiple cores and is accurate.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
92 * One way to fix this inaccuracy is by only allowing the thread to
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
93 * use one processor. Another problem is that this time will run slightly
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
94 * faster or slower than the system time.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
95 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
96 private long processorTime() {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
97 return backend_processorTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
98 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
99 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
100
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
101 unittest {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
102 auto startTime = Environment.runningTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
103 assert(startTime > 0);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
104 auto time = startTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
105 const SAMPLE = 50;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
106 // makes sure that RunningTime does not go backwards
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
107 for(int i = 0; i < SAMPLE;) {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
108 auto time2 = Environment.runningTime;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
109 assert(time2 >= time);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
110 if(time2 > time) {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
111 time = time2;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
112 ++i;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
113 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
114 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
115 //printf("avg accuracy: %.1f ms\n", (time-startTime)/cast(float)SAMPLE);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
116 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
117