/*
Copyright (C) 2022 Stephen Hewitt, cambridgeclarion.org
This file is part of a programme to research fast Fermat factorisation algorithms.
This is free software: you can redistribute it and/or modify
it under the terms of version 3 of the GNU General Public License as
published by the Free Software Foundation.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public Licence
along with this programme. If not, see .
A copy of the licence is also available at
https://www.cambridgeclarion.org/download/GPLv3.txt
It has the following cryptographic hash
SHA256 3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986
*/
/*
This programme is for research on Fermat factorisation algorithms.
This is a benchmark programme to measure and compare the performance of
a filtering algorithm implemented in different ways.
For more information see the articles on www.cambridgeclarion.org
"Empirical explorations of faster Fermat factorisation" by Stephen Hewitt
*/
#include
#include
#include
#include "timings.h"
#define ARRAYSIZE(a) (sizeof a/sizeof a[0])
typedef struct {
unsigned long category;
const char* hex;
} PQ;
class Test {
public:
unsigned long category;
const char* hex;
unsigned index; // original position in pq.gh before sorting in case we want to trace it
bool operator < (const Test& rhs) { return category < rhs.category; }
};
PQ pq[] = {
#include "pq.gh"
};
int status_message(int status, const char* message)
{
fprintf(stderr, "benchmark: error %d %s\n", status, message);
return status;
}
/*
Idea is to collect a large number of Result instances from random N values and put them in a list.
afterwards can sort by category and look at ratios of times etc within a category.
we could either let the tuned search set the category or we could find it ourselves so it is duplicated in the tuned search.
*/
void print_result(const Comparison& comp)
{
printf("%lX", comp.category);
printf(" to=%.2f;", comp.sparse.search_secs);
printf(" t=%.2f(%.2f)s t2/t1=%.2f;", comp.tuned.search_secs, comp.untuned.search_secs, comp.untuned.search_secs/comp.tuned.search_secs);
double tuned_rr = (double)comp.tuned.M/comp.tuned.tr;
double untuned_rr = (double)comp.untuned.M/comp.untuned.tr;
printf(" RR1/RR2=%.2f", tuned_rr, untuned_rr, tuned_rr/untuned_rr);
printf(" RR=%.2f(%.2f);", tuned_rr, untuned_rr, tuned_rr/untuned_rr);
printf(" M=%lu(%lu)", comp.tuned.M, comp.untuned.M);
printf(" tr=%u(%u)", comp.tuned.tr, comp.untuned.tr);
printf(" max skip=%lu(%lu)", comp.tuned.max_skip, comp.untuned.max_skip);
printf(" index=%u\n", comp.index);
putchar('\n');
printf("Tables setup t=%.2f(%.2f)s sparse=%.2f;", comp.tuned.setup_secs, comp.untuned.setup_secs, comp.sparse.setup_secs);
fflush(stdout); // try not to lose information if decide to abort the programme
}
int main(int argc, char* argv[])
{
std::vector tests;
// std::vector results;
for (unsigned ii = 0; ii < ARRAYSIZE(pq); ii++)
{
Test test;
test.hex = pq[ii].hex;
test.category = pq[ii].category;
test.index = ii;
tests.push_back(test);
}
std::sort(tests.begin(), tests.end());
// just going to do the first pq in each category for now
unsigned long last_category = 0; // 0 is not a valid category so will never match
for (auto it = tests.begin(); it != tests.end(); it++)
{
Comparison combined;
if (it->category == last_category)
continue;
last_category = it->category;
int ret = get_timings(combined, it->category, it->hex);
if (ret)
return ret;
combined.index = it->index;
combined.category = it->category;
print_result(combined);
}
/*
// since we sorted the test vector think the following is entirely redundant but leave for now
std::sort(results.begin(), results.end());
printf("Now same results but sorted follow\n");
for (auto result: results)
{
print_result(result);
}
*/
}