Giter Site home page Giter Site logo

Comments (10)

sheredom avatar sheredom commented on August 17, 2024

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.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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

image

from ubench.h.

sheredom avatar sheredom commented on August 17, 2024

Ah nice! Let me try and work it out 😄

from ubench.h.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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 ..

image

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.

sheredom avatar sheredom commented on August 17, 2024

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.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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

this is the file :

// (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.

sheredom avatar sheredom commented on August 17, 2024

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.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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.

DBJDBJ avatar DBJDBJ commented on August 17, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.