Comments (10)
If it goes into endless recursion you'd get a crash with stack overflow - so I'm not sure it is that!
from ubench.h.
if looking into test11.cpp it all works and looks simple .and very similar to my file ..
this is a windows project catching Structured Exceptions. nothing gets past that. minidump is generated and one can use it with Visual Studio to see what and where exactly has happened,
It is a stack overflow
from ubench.h.
Ah nice! Let me try and work it out 😄
from ubench.h.
Line 599 is where the call happens. As soon as it goes into that function properly created function __chkstk()
intrinsic gets called and kicks-the-bucket ..
in that file, there are some static globals but all is innocently looking? And the same stuff works blisfully in the same file but from a simple UBENCH
from ubench.h.
So I tried on a whim to call the setup code again in the UBENCH_F and everything worked.
Remember that the setup code is called once for more than one run of the UBENCH_F - so at a guess the hash table is being filled up and then its looping forever in there somehow? If I reset the hash data it seems to work.
from ubench.h.
I hope you are building using MSVC aka CL.exe and running on Win10. My setup code is never called. Not once or more than once.
Yes, that is my bad logic as that is not "set up once use always" kind of setup. Perhaps this episode deserves some more text in the readme :) But after we are sure technically this all works. On the WIN10 machine compile with the CL.exe.
As far as I can see while in a debugger something is wrong and hidden behind a UBENCH_F
macro. Debugger stops before calling it but the next step provokes a response from __chkstk()
function intrinsic to the cl.exe
from ubench.h.
So I have created a version with what macros are expanding to. It compiles and shows the stack is not functioning before even going into the first call of this benchmark loop. Stack exception is raised upon a first call of ubench_f_testu_dbj_data_dbj_uniques_arr
// (c) dbj.org -- DBJ_LICENSE -- https://dbj.org/dbj_license
#include <stdint.h>
#include <time.h>
#include "../ubench.h/ubench.h"
#ifndef _MSC_VER
#error This is Windows build only
#endif
//
// the way of 'fixtures' but without macros
// so that one can see what is happening
// on windows build
//
// https://codingforspeed.com/c-coding-example-using-hash-algorithm-to-remove-duplicate-number-by-on/
enum { TESTU_HASHSIZE = 1048576 }; // 20MB
static const int TESTU_HASH = TESTU_HASHSIZE - 1;
static int hasharr[TESTU_HASHSIZE];
// the data numbers can't be the value of TESTU_HASHSIZE,
enum { FREE_SLOT_MARK = TESTU_HASHSIZE };
enum { TESTU_MAXN = 0xFFFF };
#ifndef _WIN64
static int hashKey(long x) {
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
#else // _WIN64
static uint64_t hashKey(uint64_t x) {
x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
x = x ^ (x >> 31);
return x;
}
#endif // _WIN64
/******************************************************************/
// this is the 'fixture'
struct testu_dbj_data {
int TESTU_HASH /* = TESTU_HASHSIZE - 1 */;
int hasharr[TESTU_HASHSIZE];
long data[TESTU_MAXN] /* = { 0L }*/;
};
/******************************************************************/
static void *produce_uniques(struct testu_dbj_data *ubench_fixture) {
int count = 0;
for (int i = 0; i < TESTU_MAXN; i++) {
int key = hashKey(ubench_fixture->data[i]); // unbound hash key
key &= TESTU_HASH; // bound it to hash index
for (;;) {
if (ubench_fixture->hasharr[key] == FREE_SLOT_MARK) { // slot is available
ubench_fixture->hasharr[key] = i; // means the number appears first time
break;
} else if (ubench_fixture->data[hasharr[key]] ==
ubench_fixture->data[i]) { // same number
count++;
break;
} else {
key = (key + 1) & TESTU_HASH; // different number, collision happens
}
}
}
return ubench_fixture;
}
// this is called once from the loop function
#if 0
UBENCH_F_SETUP(testu_dbj_data)
#else
static void ubench_f_setup_testu_dbj_data(struct testu_dbj_data *ubench_fixture)
#endif
{
ubench_fixture->TESTU_HASH = TESTU_HASHSIZE - 1;
// make random data
srand(time(NULL));
for (int i = 0; i < TESTU_MAXN; i++)
ubench_fixture->data[i] = rand() % TESTU_MAXN;
// init the hash table by using the special value
for (int i = 0; i < TESTU_HASHSIZE; i++)
ubench_fixture->hasharr[i] = FREE_SLOT_MARK;
printf("\nLeaving %s", __FUNCSIG__);
}
#if 0
UBENCH_F_TEARDOWN(testu_dbj_data)
#else
static void
ubench_f_teardown_testu_dbj_data(struct testu_dbj_data *ubench_fixture)
#endif
{
memset(ubench_fixture->data, 0L, __crt_countof(ubench_fixture->data));
memset(ubench_fixture->hasharr, 0, __crt_countof(ubench_fixture->hasharr));
}
#if 0
UBENCH_F(testu_dbj_data, dbj_uniques_arr )
{
UBENCH_F_SETUP(testu_dbj_data) ;
produce_uniques( ubench_fixture ) ;
}
#else
extern struct ubench_state_s ubench_state;
static void ubench_f_setup_testu_dbj_data(struct testu_dbj_data *);
static void ubench_f_teardown_testu_dbj_data(struct testu_dbj_data *);
static void ubench_run_testu_dbj_data_dbj_uniques_arr(struct testu_dbj_data *);
/*
in here is the loop
this is registered as a benchmark function
*/
static void ubench_f_testu_dbj_data_dbj_uniques_arr
(ubench_int64_t *const ns, const ubench_int64_t size)
{
ubench_int64_t i = 0;
struct testu_dbj_data fixture;
memset(&fixture, 0, sizeof(fixture));
/* setup is called from here -- once */
ubench_f_setup_testu_dbj_data(&fixture);
for (i = 0; i < size; i++) {
ns[i] = ubench_ns();
ubench_run_testu_dbj_data_dbj_uniques_arr(&fixture);
ns[i] = ubench_ns() - ns[i];
}
ubench_f_teardown_testu_dbj_data(&fixture);
}
/*
this is the code for registering the benchmark
*/
static void __cdecl ubench_register_testu_dbj_data_dbj_uniques_arr(void);
__pragma(comment(linker, "/include:"
"ubench_register_testu_dbj_data_dbj_uniques_arr"
"_"));
__declspec(allocate(".CRT$XCU")) void(
__cdecl *ubench_register_testu_dbj_data_dbj_uniques_arr_)(void) =
ubench_register_testu_dbj_data_dbj_uniques_arr;
/*
this is the registration function itself
this *is* called before main starts
*/
static void __cdecl ubench_register_testu_dbj_data_dbj_uniques_arr(void) {
const size_t index = ubench_state.benchmarks_length++;
const char *name_part = "testu_dbj_data"
"."
"dbj_uniques_arr";
const size_t name_size = strlen(name_part) + 1;
char *name = ((char *)malloc(name_size));
ubench_state.benchmarks = ((struct ubench_benchmark_state_s *)realloc(
((void *)ubench_state.benchmarks),
sizeof(struct ubench_benchmark_state_s) *
ubench_state.benchmarks_length));
ubench_state.benchmarks[index].func =
&ubench_f_testu_dbj_data_dbj_uniques_arr;
ubench_state.benchmarks[index].name = name;
_snprintf_s(name, name_size, name_size, "%s", name_part);
}
/*
this is called from the loop
*/
void ubench_run_testu_dbj_data_dbj_uniques_arr(
struct testu_dbj_data *ubench_fixture) {
// UBENCH_F_SETUP(testu_dbj_data) ;
produce_uniques(ubench_fixture);
}
#endif // ! 0
from ubench.h.
I think the issue might be that in the UBENCH_F I stack allocate the fixture struct, and your fixture struct is massive because of the big arrays in it, so it stack overflows. Can you try heap allocating those members instead?
from ubench.h.
Probably you are right. But after almost 12 hours of fiddling-diddling :) I have decided to give up and I am going to use (again) your ubench and utest as submodules. Not my forks.
Going forward, as we have vividly seen (I think) the "fixture" feature just complicates the things and should be removed. Furthermore, utest and ubench might be better of as one header as they share common "things".
One more "detail" -- the whole thing (or is it now the whole new thing) can be implemented with no heap used. That will win a lot of new followers.
from ubench.h.
Roling back :) Just add this somewhere inside your main for the time being
#ifdef _MSC_VER
// DBJ: switch on VT100
// horrible but works on WIN10
// on other versions has no visible effect
system(" ");
#endif // _MSC_VER
:)
from ubench.h.
Related Issues (13)
- How do I use this to benchmark my functions? HOT 2
- [SOLVED] Godbolt output colouring
- How to improve confidence or reduce variance HOT 4
- Incorrect measurements using Windows + mingwx86_64 with GNU/GCC compiler HOT 1
- godbolt build requires -lm HOT 1
- Funny results when using TDM-GCC HOT 2
- Funny results on huge data sets
- MSVC color output bug ? HOT 4
- Is there an option to remove the output of the code being benchmarked HOT 1
- provide private sqrt() or mandate -lm ?
- WIN + CLANG
- Add Visual Studio / clang-cl testing HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ubench.h.