Aussie AI
Appendix C: Source Code
-
Book Excerpt from "C++ Ultra-Low Latency: Multithreading and Low-Level Optimizations"
-
by David Spuler, Ph.D.
Appendix C: Source Code
Tester Object Instrumentation Class
This code is for “object instrumentation” that can be useful for performance analysis, and also for debugging and unit testing.
Here’s a test usage to see what constructors
and move operations are performed by push_back in the std::vector class:
Tester::reset_counters();
std::vector<Tester> vectest4;
for (int i = 1; i <= 100; i++)
vectest4.push_back(i);
Tester::print_report();
Here’s the full code:
class Tester {
private: // Static data members
static bool traceall_;
static int count_default_constructor;
static int count_copy_constructor;
static int count_move_constructor;
static int count_copy_assignment;
static int count_move_assignment;
static int count_destructor;
static int count_int_constructor;
private: // Object data members
int ival_;
bool trace_;
public:
Tester() {
ival_ = 0;
count_default_constructor++;
trace_ = false;
if (traceall_) {
cout << "Tester: default constructor: " << ival_ << endl;
}
}
Tester(int val) {
count_int_constructor++;
ival_ = val;
trace_ = false;
if (traceall_) {
cout << "Tester: int constructor: " << ival_ << endl;
}
}
Tester(const Tester &other) // Copy constructor
{
ival_ = other.ival_;
trace_ = other.trace_;
count_copy_constructor++;
if (trace_ || traceall_) {
cout << "Tester: copy constructor: " << ival_ << endl;
}
}
Tester(Tester&& other) noexcept // Move constructor
{
ival_ = other.ival_;
trace_ = other.trace_;
other.ival_ = -1; // Invalidate moved data
count_move_constructor++;
if (trace_ || traceall_) {
cout << "Tester: move constructor: " << ival_ << endl;
}
}
Tester& operator=(const Tester& other) // Copy assign
{
count_copy_assignment++;
if (this != &other) { // Avoid aliasing
ival_ = other.ival_;
if (trace_ || traceall_) {
cout << "Tester: copy assignment: " << ival_ << endl;
}
}
else {
if (trace_ || traceall_) {
cout << "Tester: copy assignment aliasing: " << ival_ << endl;
}
}
return *this;
}
Tester& operator=(Tester&& other) noexcept // Move assign
{
count_move_assignment++;
if (this != &other) { // Avoid aliasing
ival_ = other.ival_;
if (trace_ || traceall_) {
cout << "Tester: move assignment: " << ival_ << endl;
}
}
else {
if (trace_ || traceall_) {
cout << "Tester: move assignment aliasing: " << ival_ << endl;
}
}
other.ival_ = -1; // Invalidate moved data
return *this;
}
~Tester()
{
count_destructor++;
if (trace_ || traceall_) {
cout << "Tester: destructor: " << ival_ << endl;
}
ival_ = -1; // Safety
}
// Equality operators
bool operator==(const Tester& other) { return ival_ == other.ival_; }
// Setters for object members
void trace(bool bval) { trace_ = bval; }
// Setters for static data members
static void traceall(bool bval) { traceall_ = bval; }
static void reset_counters() {
count_default_constructor = 0;
count_copy_constructor = 0;
count_move_constructor = 0;
count_copy_assignment = 0;
count_move_assignment = 0;
count_destructor = 0;
count_int_constructor = 0;
}
static void print_report() {
cout << "Tester Count Report" << endl;
cout << "- Default constructor: " << count_default_constructor << endl;
cout << "- Int constructor: " << count_int_constructor << endl;
cout << "- Copy constructor: " << count_copy_constructor << endl;
cout << "- Move constructor: " << count_move_constructor << endl;
cout << "- Copy assignment: " << count_copy_assignment << endl;
cout << "- Move assignment: " << count_move_assignment << endl;
cout << "- Destructor: " << count_destructor << endl;
}
static void selftest() {
// Constructors should equal destructors
// ... but move constructors don’t increase the count
int errors = 0;
int total_constructors = count_default_constructor + count_int_constructor + count_copy_constructor;
if (total_constructors != count_destructor) {
if (total_constructors > count_destructor) {
cout << "Tester selftest: constructors (" << total_constructors
<< ") more than destructors (" << count_destructor << ")" << endl;
errors++;
}
else {
cout << "Tester selftest: destructors (" << count_destructor
<< ") more than constructors (" << total_constructors << ")" << endl;
errors++;
}
}
if (errors == 0) {
cout << "Tester selftest: no errors found" << endl;
}
}
};
// Define Tester static data members
bool Tester::traceall_ = false;
int Tester::count_default_constructor = 0;
int Tester::count_copy_constructor = 0;
int Tester::count_move_constructor = 0;
int Tester::count_copy_assignment = 0;
int Tester::count_move_assignment = 0;
int Tester::count_destructor = 0;
int Tester::count_int_constructor = 0;
Intercepted new and delete
This source code is the global scope intercept functions for the new and delete operators.
The library tracks basic statistics about calls and bytes allocated.
// Global counters
unsigned long int s_new_count = 0;
unsigned long int s_newarr_count = 0;
unsigned long int s_delete_count = 0;
unsigned long int s_deletearr_count = 0;
unsigned long int s_new_bytes = 0;
unsigned long int s_newarr_bytes = 0;
void memory_reset_counters()
{
s_new_count = 0;
s_newarr_count = 0;
s_delete_count = 0;
s_deletearr_count = 0;
s_new_bytes = 0;
s_newarr_bytes = 0;
}
void memory_report()
{
cout << "MEMORY CALLS REPORT" << endl;
cout << "- new calls: " << s_new_count << endl;
cout << "- new[] calls: " << s_newarr_count << endl;
cout << "- delete calls: " << s_delete_count << endl;
cout << "- delete[] calls: " << s_deletearr_count << endl;
cout << "MEMORY SIZE REPORT" << endl;
cout << "- new bytes: " << s_new_bytes << endl;
cout << "- new[] bytes: " << s_newarr_bytes << endl;
}
void* operator new(size_t n)
{
s_new_count++;
s_new_bytes += n;
return malloc(n);
}
void* operator new[](size_t n)
{
s_newarr_count++;
s_newarr_bytes += n;
return malloc(n);
}
void operator delete(void* v)
{
s_delete_count++;
free(v);
}
void operator delete[](void* v)
{
s_deletearr_count++;
free(v);
}
|
• Online: Table of Contents • PDF: Free PDF book download • Buy: C++ Ultra-Low Latency |
|
C++ Ultra-Low Latency: Multithreading and Low-Level Optimizations:
Get your copy from Amazon: C++ Ultra-Low Latency |