repo cleanup, added actual README
This commit is contained in:
parent
d1343ff90c
commit
2035c1e10e
13 changed files with 62 additions and 47 deletions
58
README.md
58
README.md
|
|
@ -1,18 +1,44 @@
|
||||||
# tmr
|
x86 TSC-based tick timer written in C++ and extended ASM.
|
||||||
|
|
||||||
no sé si desde dentro del dll/so, desde main, lo puedo forzar a X hilo. Es lo que faltaría para tener esta impl 100% funcional*
|
This timer queries RDTSCP/RDTSC manually on compatible systems and presents a quick and easy-to-use interface to obtain timestamps. On Windows, this is basically what `QueryPerformanceCounter` achieves behind the curtains (and with fallbacks where not applicable, like HPET), but with lower resolution.
|
||||||
[20:59]
|
|
||||||
no puedo hacerlo bien del todo sin acceso a un procesador intel de 12a o 13a generación (editado)
|
|
||||||
[21:00]
|
|
||||||
si pudiese clampear la dll a hilo X desde ella misma cuando ntdll la carga, al menos estaría todo bien hardcodeadito al hilo 0 y funcionaría por el poder de ser un mugroso
|
|
||||||
[21:00]
|
|
||||||
va a funcionar igual en el 9X% de casos, porque todos los so intentan sincronizar el tsc de todos los hilos hasta en multisocket
|
|
||||||
[21:00]
|
|
||||||
pero eso está técnicamente mal
|
|
||||||
[21:01]
|
|
||||||
y bueno, necesito un procesador de intel más reciente para explorar el cálculo del ART, y 12/13 gen para explorar el tsc entre hilos de cpu de distinta uarch
|
|
||||||
[21:01]
|
|
||||||
no va a pasar, así que a joderse
|
|
||||||
[21:02]
|
|
||||||
intentaré clampear desde dll a un hilo, pondré el Modo Unix™️ y a otra cosa
|
|
||||||
|
|
||||||
|
While functional on some CPU families (Zen/+ and Haswell have been tested), this library is not ready for use. Linux support is TBD, alongside testing on different CPU families and implementing support for heterogeneous architectures and products (such as Tiger Lake+/Zen4+Zen4c systems).
|
||||||
|
|
||||||
|
Worth noting as well is the fact that [calculating TSC resolution from user-space on an AMD CPU is not possible.](https://github.com/jdmccalpin/low-overhead-timers/issues/1) Precise enough estimations can be calculated, but this artificial limitation adds a non-insignificant level of friction to this project.
|
||||||
|
|
||||||
|
A small console program to test this library and comparing it agains `QueryPerformancecounter` is provided, busywaiting for a second and comparing both.
|
||||||
|
|
||||||
|
# But why?
|
||||||
|
|
||||||
|
During development of the mouse-on-keyboard script, I grew curious about this topic. Win32's `Sleep()` is a reliably unreliable time-skipping measure, subject to the wishes of thread time-slicing and scheduling. High resolution timers in the vein of `QueryPerformanceCounter` are what Win32 offers in this regard, but a spark of interest and curiosity had already grown about this topic. I created this library, this incomplete pet-project, as a means to learn and refresh knowledge about x86 ASM, registry traversal and modification, modern OSes, current x86 hardware features and shared libraries.
|
||||||
|
|
||||||
|
# How to build
|
||||||
|
|
||||||
|
## Build requirements
|
||||||
|
|
||||||
|
- Both test and Developed and tested with `clang` using [**llvm-mingw UCRT 20220906**](https://github.com/mstorsjo/llvm-mingw/releases/tag/20220906). Any `MinGW`-backed `clang` compiler should work, but your mileage may vary.
|
||||||
|
- This lib has only been compiled and tested as a dynamic lib, but it should work statically linked as well.
|
||||||
|
|
||||||
|
## How to compile
|
||||||
|
|
||||||
|
Add `TMRDEBUG` to print debug information. Currently, it only offers relevant information for ART calculation.
|
||||||
|
|
||||||
|
- Library
|
||||||
|
|
||||||
|
```
|
||||||
|
clang++ -shared src\tmrtsc.cpp -o libtmrtsc.dll -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -Wl,-Bstatic -l c++ --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
- Test
|
||||||
|
|
||||||
|
```
|
||||||
|
clang++ src\test\test.cpp -o testd.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -L . -Wl,-Bstatic -l c++ -Wl,-Bdynamic -l tmrtsc --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
# Bonus
|
||||||
|
|
||||||
|
This repo contains this project's prototipe in `.\src\proto`, which can be messed with build very similarly:
|
||||||
|
|
||||||
|
```
|
||||||
|
clang++ src\proto\proto.cpp -o proto.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -static-libstdc++ --verbose
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
REM MS yo me cago en tus putisimos muertos que cojones es este bug centenario estupido y miserable con los parametros?
|
|
||||||
REM este comentario es de cuando me lo encontre hace rato, pero me hace gracia, asi que se queda
|
|
||||||
|
|
||||||
CALL buildlib.bat
|
|
||||||
CALL buildtest.bat
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
REM MS yo me cago en tus putisimos muertos que cojones es este bug centenario estupido y miserable con los parametros?
|
|
||||||
REM este comentario es de cuando me lo encontre hace rato, pero me hace gracia, asi que se queda
|
|
||||||
|
|
||||||
CALL builddlib.bat
|
|
||||||
CALL builddtest.bat
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
clang++ -DDEBUG -D_DEBUG -shared src\tmrtsc.cpp -o build\libtmrtscd.dll -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -Wl,-Bstatic -l c++ -l unwind --verbose
|
|
||||||
|
|
||||||
REM -lmsvcrt -lucrtbase -lvcruntime140_app
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
clang++ -DDEBUG -D_DEBUG -dynamic src\test\test.cpp -o build\testd.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -L D:\Contenido\Capybara\Cositas\tmr\build -Wl,-Bstatic -l c++ -l unwind -Wl,-Bdynamic -l tmrtsc --verbose
|
|
||||||
|
|
||||||
REM -fms-runtime-lib dll_dbgx
|
|
||||||
REM -lmsvcrt -lucrtbase -lvcruntime140_app
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
clang++ -shared src\tmrtsc.cpp -o build\libtmrtsc.dll -Wall -Wextra -Wpedantic -std=c++11 -L C:\capybara\libclang\x86_64-w64-mingw32\bin -Wl,-Bstatic -l c++ -l unwind --verbose
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
clang++ -DDEBUG src\proto\proto.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -static-libstdc++ -static --verbose
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
clang++ -dynamic src\test\test.cpp -o build\test.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\capybara\libclang\x86_64-w64-mingw32\bin -L D:\Contenido\Capybara\Cositas\tmr\build -Wl,-Bstatic -l c++ -l unwind -Wl,-Bdynamic -l tmrtsc --verbose
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined (QT_DEBUG) || defined (DEBUG) || defined (_DEBUG)
|
#ifdef TMRDEBUG
|
||||||
|
|
||||||
#define log_debugcpp(str) do { \
|
#define log_debugcpp(str) do { \
|
||||||
std::cout << "[DEBUG]" << "(" << __FILE__ << ":" << __LINE__ << "): " << str << std::endl; \
|
std::cout << "[DEBUG]" << "(" << __FILE__ << ":" << __LINE__ << "): " << str << std::endl; \
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* THREADIN THE LINUS: https://linux.die.net/man/2/sched_setaffinity
|
* THREADIN THE LINUS: https://linux.die.net/man/2/sched_setaffinity
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,6 +28,11 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B
|
||||||
|
|
||||||
//https://github.com/jdmccalpin/low-overhead-timers/issues/1
|
//https://github.com/jdmccalpin/low-overhead-timers/issues/1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* no sé si desde dentro del dll/so, desde main, lo puedo forzar a X hilo. Es lo que faltaría para tener esta impl 100% funcional* [20:59] no puedo hacerlo bien del todo sin acceso a un procesador intel de 12a o 13a generación (editado) [21:00] si pudiese clampear la dll a hilo X desde ella misma cuando ntdll la carga, al menos estaría todo bien hardcodeadito al hilo 0 y funcionaría por el poder de la dureza [1:00] va a funcionar igual en el 9X% de casos, porque todos los so intentan sincronizar el tsc de todos los hilos hasta en multisocket [21:00] pero eso está técnicamente mal [21:01] y bueno, necesito un procesador de intel más reciente para explorar el cálculo del ART, y 12/13 gen para explorar el tsc entre hilos de cpu de distinta uarch [21:01] no va a pasar, así que a joderse [21:02] intentaré clampear desde dll a un hilo, pondré el Modo Unix™️ y a otra cosa
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
//#include <Windows.h>
|
//#include <Windows.h>
|
||||||
//#includqe <sysinfoapi.h>
|
//#includqe <sysinfoapi.h>
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#define DllImport __declspec( dllimport )
|
#define DllImport __declspec( dllimport )
|
||||||
#define _MT
|
// #define _MT
|
||||||
#define _DLL
|
// #define _DLL
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <fileapi.h>
|
#include <fileapi.h>
|
||||||
//#include <libloaderapi.h>
|
//#include <libloaderapi.h>
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,12 @@ namespace tmr {
|
||||||
int byte = 0;
|
int byte = 0;
|
||||||
for (int reg = 0; reg < 3; reg++, byte = 0){
|
for (int reg = 0; reg < 3; reg++, byte = 0){
|
||||||
char* charifiedReg = (char*)®s[reg];
|
char* charifiedReg = (char*)®s[reg];
|
||||||
for(; byte < 4; byte++, siguienteLetra++ ){
|
for(; byte < 4; byte++, siguienteLetra++) {
|
||||||
palabritas[siguienteLetra] = charifiedReg[byte];
|
palabritas[siguienteLetra] = charifiedReg[byte];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
palabritas[siguienteLetra] = '\0';
|
palabritas[siguienteLetra] = '\0';
|
||||||
|
log_debugcpp(palabritas);
|
||||||
return palabritas;
|
return palabritas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,7 +148,7 @@ namespace tmr {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool TSCTimer::checkRDTSCP(){ //Generic
|
bool TSCTimer::checkRDTSCP() { //Generic
|
||||||
uint64_t rdx;
|
uint64_t rdx;
|
||||||
asm volatile (".intel_syntax noprefix\t\n" \
|
asm volatile (".intel_syntax noprefix\t\n" \
|
||||||
"mov eax, 0x80000001\t\n" \
|
"mov eax, 0x80000001\t\n" \
|
||||||
|
|
@ -179,6 +180,11 @@ namespace tmr {
|
||||||
TSCTimer* TSCTimer::getTimer() {
|
TSCTimer* TSCTimer::getTimer() {
|
||||||
if (!checkInvariantTSC()) return nullptr;
|
if (!checkInvariantTSC()) return nullptr;
|
||||||
//TODO debug dis
|
//TODO debug dis
|
||||||
|
#if defined TMRDEBUG && defined _WIN64
|
||||||
|
//AttachConsole(ATTACH_PARENT_PROCESS );
|
||||||
|
log_debugcpp("TSC Timer debug enabled.");
|
||||||
|
//FreeConsole();
|
||||||
|
#endif
|
||||||
const char vendorNames[2][13] = {
|
const char vendorNames[2][13] = {
|
||||||
{"AuthenticAMD"},
|
{"AuthenticAMD"},
|
||||||
{"GenuineIntel"}
|
{"GenuineIntel"}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WIN10 //0x0A00
|
#define _WIN32_WINNT _WIN32_WINNT_WIN10 //0x0A00
|
||||||
#define MAX_KEY_LENGTH 255
|
#define MAX_KEY_LENGTH 255
|
||||||
#define MAX_VALUE_NAME 32767
|
#define MAX_VALUE_NAME 32767
|
||||||
#define _MT
|
// #define _MT
|
||||||
#define _DLL
|
// #define _DLL
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <winreg.h>
|
#include <winreg.h>
|
||||||
#include <stringapiset.h>
|
#include <stringapiset.h>
|
||||||
|
|
@ -18,12 +18,10 @@
|
||||||
#define LIB_EXPORT
|
#define LIB_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
#if _WIN64
|
#if _WIN64
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue