misc.c: add a few basic clock functions

This commit is contained in:
2024-03-28 08:33:27 +01:00
parent ad704c216b
commit ad8a9609ce
5 changed files with 160 additions and 34 deletions

View File

@@ -89,10 +89,10 @@ CFLAGS := -std=gnu11
### dev OR release
# dev
CFLAGS += -O1
#CFLAGS += -O1
#CFLAGS += -g
# release
#CFLAGS += -Ofast
CFLAGS += -Ofast
CFLAGS += -march=native
CFLAGS += -flto
@@ -100,7 +100,7 @@ CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -Wmissing-declarations
# for gprof
CFLAGS += -pg
#CFLAGS += -pg
# Next one may be useful for valgrind (when invalid instructions)
# CFLAGS += -mno-tbm
@@ -309,7 +309,7 @@ BB_OBJS := $(FEN_OBJS)
MOVEGEN_OBJS := $(BB_OBJS) move.o move-gen.o
ATTACK_OBJS := $(MOVEGEN_OBJS)
MOVEDO_OBJS := $(ATTACK_OBJS) move-do.o
PERFT_OBJS := $(MOVEDO_OBJS) search.o
PERFT_OBJS := $(MOVEDO_OBJS) search.o misc.o
TEST := $(addprefix $(BINDIR)/,$(TEST))

View File

@@ -134,5 +134,35 @@ typedef enum {
NORTH_WEST = (NORTH + WEST),
} dir_t;
#include <time.h>
typedef struct mclock {
clockid_t clocktype;
ulong elapsed_l;
double elapsed_f;
struct timespec start;
} mclock_t;
#define CLOCK_WALL CLOCK_REALTIME
#define CLOCK_SYSTEM CLOCK_MONOTONIC_RAW
#define CLOCK_PROCESS CLOCK_PROCESS_CPUTIME_ID
#define CLOCK_THREAD CLOCK_THREAD_CPUTIME_ID
/**
* CLOCK_DEFINE - define a clock type.
* @name: clock name
* @type: clock type
*
* This macro is equivalent to:
* mclock_t name;
* clock_init(&name, type);
*/
#define CLOCK_DEFINE(name, type) struct mclock name = { .clocktype = type }
void clock_init(mclock_t *clock, clockid_t type);
void clock_start(mclock_t *clock);
s64 clock_elapsed_μs(mclock_t *clock);
s64 clock_elapsed_ms(mclock_t *clock);
double clock_elapsed_sec(mclock_t *clock);
#endif /* _CHESSDEFS_H */

112
src/misc.c Normal file
View File

@@ -0,0 +1,112 @@
/* misc.c - generic/catchall functions.
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <time.h>
#include "chessdefs.h"
/*
* 1 sec = 1000 millisec
* 1 millisec = 1000 microsec
* 1 microsec = 1000 nanosec
* milli = sec * 1000 + nanosec / 1000000
*
*/
/* We use microsec for all intermediate calcluation */
#define NANO_IN_MICRO 1000ll /* nanosecond in millisecond */
#define MICRO_IN_SEC 1000000ll /* millisecond in second */
#define MILLI_IN_SEC 1000ll /* millisecond in second */
#define MICRO_IN_MILLI 1000ll
//#define NANO_IN_MILLI 1000000ll /* nanosecond in millisecond */
//#define NANO_IN_SEC (NANOS_IN_MS * MS_IN_SEC)
/**
* clock_start - start or restart a clock.
* @clock: &mclock_t clock
*
* Save current time according to @clock type.
*/
void clock_start(mclock_t *clock)
{
clock_gettime(clock->clocktype, &clock->start);
}
/**
* clock_init - initializes a clock type.
* @clock: &mclock_t clock
* @type: clock type
*
* See the clock_gettime(2) for details.
* CLOCK_WALL (a.k.a CLOCK_REALTIME): Wall clock.
* CLOCK_SYSTEM (a.k.a CLOCK_MONOTONIC_RAW): System clock.
* CLOCK_PROCESS (a.k.a CLOCK_PROCESS_CPUTIME_ID): Process CPU clock (incl. threads).
* CLOCK_THREAD (a.k.a CLOCK_THREAD_CPUTIME_ID): Thread CPU clock.
*/
void clock_init(mclock_t *clock, clockid_t type)
{
clock->clocktype = type;
clock_start(clock);
}
/**
* clock_elapsed_μs - return a mclock_t elapsed time in microseconds.
* @clock: &mclock_t clock
*
* The elapsed time is calculated between current time and last clock_start(@clock)
* call time.
*
* @return: microseconds elapsed since last clock_start().
*/
s64 clock_elapsed_μs(mclock_t *clock)
{
struct timespec current;
s64 μs;
clock_gettime(clock->clocktype, &current);
μs = ((s64)current.tv_sec - (s64)clock->start.tv_sec) * MICRO_IN_SEC +
((s64)current.tv_nsec - (s64)clock->start.tv_nsec) / NANO_IN_MICRO ;
return μs;
}
/**
* clock_elapsed_ms - return a mclock_t elapsed time in milliseconds.
* @clock: &mclock_t clock
*
* The elapsed time is calculated between current time and last clock_start(@clock)
* call time.
*
* @return: milliseconds elapsed since last clock_start().
*/
s64 clock_elapsed_ms(mclock_t *clock)
{
return clock_elapsed_μs(clock) / MICRO_IN_MILLI;
}
/**
* clock_elapsed_sec - return a mclock_t elapsed time in seconds.
* @clock: &mclock_t clock
*
* The elapsed time is calculated between current time and last clock_start(@clock)
* call time.
*
* @return: seconds elapsed since last clock_start().
*/
double clock_elapsed_sec(mclock_t *clock)
{
return (double) clock_elapsed_μs(clock) / (double) MICRO_IN_SEC;
}

View File

@@ -21,9 +21,6 @@
#include "search.h"
#include "attack.h"
//#include "move.h"
//#include "eval.h"
/**
* perft() - Perform perft on position
* @pos: &position to search
@@ -63,7 +60,7 @@ u64 perft(pos_t *pos, int depth, int ply)
}
if (ply == 1)
printf("\nTotal: %lu\n", nodes);
printf("Total: %lu\n", nodes);
return nodes;
}
@@ -88,19 +85,19 @@ u64 perft2(pos_t *pos, int depth, int ply)
for (nmove = 0; nmove < pseudo.nmoves; ++nmove ) {
move = pseudo.move[nmove];
move_do(pos, move);
//if (!is_in_check(pos, OPPONENT(pos->turn))) {
subnodes = perft2(pos, depth - 1, ply + 1);
nodes += subnodes;
if (ply == 1) {
char movestr[8];
printf("%s: %d\n", move_str(movestr, move, 0), subnodes);
}
//}
move_undo(pos, move);
pos->state = state;
}
if (ply == 1)
printf("\nTotal: %lu\n", nodes);
printf("Total: %lu\n", nodes);
return nodes;
}

View File

@@ -256,41 +256,28 @@ int main(int __unused ac, __unused char**av)
savepos = pos_dup(pos);
//int j = 0;
#define NANOSEC 1000000000 /* nano sec in sec */
#define MILLISEC 1000000 /* milli sec in sec */
s64 μs;
CLOCK_DEFINE(clock, CLOCK_SYSTEM);
// 1 sec = 1000 millisec
// 1 millisec = 1000 microsec
// 1 microsec = 1000 nanosec
// milli = sec * 1000 + nanosec / 1000000
struct timespec ts1, ts2;
s64 microsecs;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts1);
clock_start(&clock);
my_count = perft(pos, depth, 1);
clock_gettime(CLOCK_MONOTONIC_RAW, &ts2);
μs = clock_elapsed_μs(&clock);
microsecs = ((s64)ts2.tv_sec - (s64)ts1.tv_sec) * 1000000l
+ ((s64)ts2.tv_nsec - (s64)ts1.tv_nsec) / 1000l ;
if (sf_count == my_count) {
printf("pt1 OK : line=%03d perft=%lu ms=%'ldms lps=%'lu \"%s\"\n",
test_line, my_count, microsecs/1000l,
my_count*1000000l/microsecs, fen);
printf("pt1 OK : line=%03d perft=%lu μs=%'ldms lps=%'lu \"%s\"\n",
test_line, my_count, μs, my_count*1000000l/μs, fen);
} else {
printf("pt1 ERR: line=%03d sf=%lu me=%lu \"%s\"\n",
test_line, sf_count, my_count, fen);
}
clock_gettime(CLOCK_MONOTONIC_RAW, &ts1);
clock_start(&clock);
my_count = perft2(pos, depth, 1);
clock_gettime(CLOCK_MONOTONIC_RAW, &ts2);
μs = clock_elapsed_μs(&clock);
microsecs = ((s64)ts2.tv_sec - (s64)ts1.tv_sec) * 1000000l
+ ((s64)ts2.tv_nsec - (s64)ts1.tv_nsec) / 1000l ;
if (sf_count == my_count) {
printf("pt2 OK : line=%03d perft=%lu ms=%'ldms lps=%'lu \"%s\"\n\n",
test_line, my_count, microsecs/1000l,
my_count*1000000l/microsecs, fen);
printf("pt2 OK : line=%03d perft=%lu μs=%'ldms lps=%'lu \"%s\"\n\n",
test_line, my_count, μs, my_count*1000000l/μs, fen);
} else {
printf("pt2 ERR: line=%03d sf=%lu me=%lu \"%s\"\n\n",
test_line, sf_count, my_count, fen);