Skip to content

Instantly share code, notes, and snippets.

@LPardue
Created April 13, 2017 14:28
Show Gist options
  • Save LPardue/64b555ecc70b7abe85fc96bb37f2f4f8 to your computer and use it in GitHub Desktop.
Save LPardue/64b555ecc70b7abe85fc96bb37f2f4f8 to your computer and use it in GitHub Desktop.
PADDING performance testing
#include <iostream>
#include <memory>
#include <chrono>
#include <vector>
#include <cstdint>
/*
* This program tests some mock QUIC PADDING frames.
* The general approach is to have a buffer full of padding
* with the final byte as some imaginary frame type (0xA).
* In Test A, a 1 Byte PADDING frame is tested.
* There are BUFF_SIZE-1 PADDING frames followed by the
* imaginary frame type.
*
*
* In Test B, a N Byte PADDING frame is tested where the first
* 3 bytes are used as such:
*
* Byte 1: Frame type (0x00)
* Byte 2: Padding size MSB
* Byte 3: Padding size LSB
*
* There is BUFF_SIZE-3 bytes of padding followed by the
* imaginary frame type.
*/
int main() {
const uint16_t BUFF_SIZE = 65000;
uint8_t buff[BUFF_SIZE];
uint8_t iterations = 100;
bool found = false;
const uint8_t PADDING_FRAME = 0;
const uint8_t IMAGINARY_FRAME = 10;
std::vector<std::chrono::nanoseconds::rep> buffer_times;
std::vector<std::chrono::nanoseconds::rep> frame_times;
uint8_t frame_type = 0;
auto frame_begin = std::chrono::high_resolution_clock::now();
auto frame_end = std::chrono::high_resolution_clock::now();
std::fill( buff, buff + BUFF_SIZE, 0 );
buff[BUFF_SIZE -1 ] = IMAGINARY_FRAME;
auto frame_stats = false;
// Begin test A
for (int j=0; j < iterations; j++) {
auto buffer_begin = std::chrono::high_resolution_clock::now();
for(int i=0; i < BUFF_SIZE; i++) {
if (!frame_stats) {
frame_type = buff[i];
} else {
frame_begin = std::chrono::high_resolution_clock::now();
frame_type = buff[i];
frame_end = std::chrono::high_resolution_clock::now();
frame_times.push_back(std::chrono::duration_cast<std::chrono::nanoseconds>(frame_end-frame_begin).count());
}
if (frame_type == PADDING_FRAME) {
// nothing to do
}
else if (frame_type == IMAGINARY_FRAME) {
found = true;
}
}
auto buffer_end = std::chrono::high_resolution_clock::now();
buffer_times.push_back(std::chrono::duration_cast<std::chrono::nanoseconds>(buffer_end-buffer_begin).count());
}
if (found)
std::cout << "Imaginary frame found" << std::endl;
std::cout << "Test type A - buffer reads" <<std::endl;
for (auto bt: buffer_times) {
std::cout << bt << "\n";
}
std::cout << "\n" << std::endl;
if (frame_stats) {
std::cout << "Test type A - frame reads" <<std::endl;
for (auto bt: frame_times) {
std::cout << bt << "\n";
}
std::cout << "\n" << std::endl;
}
// Setup of Test B
// Set alternative PADDING length in bytes 2 and 3
uint16_t pad_len_frame_val = BUFF_SIZE - 3;
buff[1] = pad_len_frame_val >> 8;
buff[2] = pad_len_frame_val;
// reset things
found = false;
buffer_times.clear();
frame_times.clear();
for (int j=0; j < iterations; j++) {
auto buffer_begin = std::chrono::high_resolution_clock::now();
for(int i=0; i < BUFF_SIZE; i++) {
if (frame_stats) {
frame_begin = std::chrono::high_resolution_clock::now();
}
frame_type = buff[i];
if (frame_type == PADDING_FRAME) {
auto pad_length = (buff[i+1] << 8) | buff[i+2];
if (frame_stats) {
frame_end = std::chrono::high_resolution_clock::now();
frame_times.push_back(std::chrono::duration_cast<std::chrono::nanoseconds>(frame_end-frame_begin).count());
}
// index of next Frame byte is 2 bytes + padding length (-1 to accomodate loop counter increment)
i = i+2+pad_length-1;
} else if (frame_type == IMAGINARY_FRAME) {
found = true;
}
}
auto buffer_end = std::chrono::high_resolution_clock::now();
buffer_times.push_back(std::chrono::duration_cast<std::chrono::nanoseconds>(buffer_end-buffer_begin).count());
}
if (found)
std::cout << "Imaginary frame found" << std::endl;
std::cout << "Test type B - buffer reads" <<std::endl;
for (auto bt: buffer_times) {
std::cout << bt << "\n";
}
std::cout << "\n" << std::endl;
if (frame_stats) {
std::cout << "Test type B - frame reads" <<std::endl;
for (auto bt: frame_times) {
std::cout << bt << "\n";
}
std::cout << "\n" << std::endl;
}
}
@LPardue
Copy link
Author

LPardue commented Apr 13, 2017

Making it work:

g++ -std=c++11 buffer_read.cpp -o buffer_read
./buffer_read

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment