Changeset ef3c383


Ignore:
Timestamp:
Mar 21, 2022, 1:43:58 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
d672350
Parents:
3a40df6
Message:

Added statistics about sendfile in the webserver

Location:
benchmark/io/http
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • benchmark/io/http/main.cfa

    r3a40df6 ref3c383  
    3333//============================================================================================='
    3434
    35 thread StatsPrinter {};
     35thread StatsPrinter {
     36        Worker * workers;
     37        int worker_cnt;
     38};
    3639
    3740void ?{}( StatsPrinter & this, cluster & cl ) {
    3841        ((thread&)this){ "Stats Printer Thread", cl };
     42        this.worker_cnt = 0;
    3943}
    4044
    4145void ^?{}( StatsPrinter & mutex this ) {}
     46
     47#define eng3(X) (ws(3, 3, unit(eng( X ))))
    4248
    4349void main(StatsPrinter & this) {
     
    5157
    5258                print_stats_now( *active_cluster(), CFA_STATS_READY_Q | CFA_STATS_IO );
     59                if(this.worker_cnt != 0) {
     60                        uint64_t tries = 0;
     61                        uint64_t calls = 0;
     62                        uint64_t header = 0;
     63                        uint64_t splcin = 0;
     64                        uint64_t splcot = 0;
     65                        struct {
     66                                volatile uint64_t calls;
     67                                volatile uint64_t bytes;
     68                        } avgrd[zipf_cnts];
     69                        memset(avgrd, 0, sizeof(avgrd));
     70
     71                        for(i; this.worker_cnt) {
     72                                tries += this.workers[i].stats.sendfile.tries;
     73                                calls += this.workers[i].stats.sendfile.calls;
     74                                header += this.workers[i].stats.sendfile.header;
     75                                splcin += this.workers[i].stats.sendfile.splcin;
     76                                splcot += this.workers[i].stats.sendfile.splcot;
     77                                for(j; zipf_cnts) {
     78                                        avgrd[j].calls += this.workers[i].stats.sendfile.avgrd[j].calls;
     79                                        avgrd[j].bytes += this.workers[i].stats.sendfile.avgrd[j].bytes;
     80                                }
     81                        }
     82
     83                        double ratio = ((double)tries) / calls;
     84
     85                        sout | "----- Worker Stats -----";
     86                        sout | "sendfile  : " | calls | "calls," | tries | "tries (" | ratio | " try/call)";
     87                        sout | "            " | header | "header," | splcin | "splice in," | splcot | "splice out";
     88                        sout | " - zipf sizes:";
     89                        for(i; zipf_cnts) {
     90                                double written = avgrd[i].calls > 0 ? ((double)avgrd[i].bytes) / avgrd[i].calls : 0;
     91                                sout | "        " | zipf_sizes[i] | "bytes," | avgrd[i].calls | "shorts," | written | "written";
     92                        }
     93                }
     94                else {
     95                        sout | "No Workers!";
     96                }
    5397        }
    5498}
     
    218262                        {
    219263                                Worker * workers = anew(options.clopts.nworkers);
     264                                cl[0].prnt->workers = workers;
     265                                cl[0].prnt->worker_cnt = options.clopts.nworkers;
    220266                                for(i; options.clopts.nworkers) {
    221267                                        // if( options.file_cache.fixed_fds ) {
     
    311357        }
    312358}
     359
     360const size_t zipf_sizes[] = { 102, 204, 307, 409, 512, 614, 716, 819, 921, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 20480, 30720, 40960, 51200, 61440, 71680, 81920, 92160, 102400, 204800, 307200, 409600, 512000, 614400, 716800, 819200, 921600 };
     361static_assert(zipf_cnts == sizeof(zipf_sizes) / sizeof(zipf_sizes[0]));
  • benchmark/io/http/parhttperf

    r3a40df6 ref3c383  
    66
    77mkdir -p out
    8 rm -v out/*
     8rm out/*
     9echo "httperf --client [0-$(($NTHREADS - 1))]/$NTHREADS $@ > out/result.[0-$(($NTHREADS - 1))].out"
    910for ((i=0; i<$NTHREADS; i++))
    1011do
    11         # echo "httperf --client $i/$NTHREADS $@ > out/result.$i.out"
    1212        httperf --client $i/$NTHREADS $@ > out/result.$i.out &
    1313done
  • benchmark/io/http/protocol.cfa

    r3a40df6 ref3c383  
    2424
    2525#include "options.hfa"
     26#include "worker.hfa"
    2627
    2728#define PLAINTEXT_1WRITE
     
    156157
    157158                count -= ret;
    158                 offset += ret;
    159159                size_t in_pipe = ret;
    160160                SPLICE2: while(in_pipe > 0) {
     
    266266}
    267267
    268 static inline int wait_and_process(header_g & this) {
     268static inline int wait_and_process(header_g & this, sendfile_stats_t & stats) {
    269269        wait(this.f);
    270270
     
    295295        }
    296296
     297        stats.header++;
     298
    297299        // It must be a Short read
    298300        this.len  -= this.f.result;
     
    306308        io_future_t f;
    307309        int fd; int pipe; size_t len; off_t off;
     310        short zipf_idx;
    308311        FSM_Result res;
    309312};
     
    314317        this.len = len;
    315318        this.off = 0;
     319        this.zipf_idx = -1;
     320        STATS: for(i; zipf_cnts) {
     321                if(len <= zipf_sizes[i]) {
     322                        this.zipf_idx = i;
     323                        break STATS;
     324                }
     325        }
     326        if(this.zipf_idx < 0) mutex(serr) serr | "SPLICE IN" | len | " greated than biggest zipf file";
    316327}
    317328
     
    329340}
    330341
    331 static inline int wait_and_process(splice_in_t & this) {
     342static inline int wait_and_process(splice_in_t & this, sendfile_stats_t & stats ) {
    332343        wait(this.f);
    333344
     
    345356                        return error(this.res, -ECONNRESET);
    346357                }
     358                mutex(serr) serr | "SPLICE IN got" | error | ", WTF!";
     359                return error(this.res, -ECONNRESET);
    347360        }
    348361
     
    357370                return done(this.res);
    358371        }
     372
     373        stats.splcin++;
     374        stats.avgrd[this.zipf_idx].calls++;
     375        stats.avgrd[this.zipf_idx].bytes += this.f.result;
    359376
    360377        // It must be a Short read
     
    398415}
    399416
    400 static inline void wait_and_process(splice_out_g & this) {
     417static inline void wait_and_process(splice_out_g & this, sendfile_stats_t & stats ) {
    401418        wait(this.f);
    402419
     
    414431                        return error(this, -ECONNRESET);
    415432                }
     433                mutex(serr) serr | "SPLICE OUT got" | error | ", WTF!";
     434                return error(this, -ECONNRESET);
    416435        }
    417436
     
    428447
    429448SHORT_WRITE:
     449        stats.splcot++;
     450
    430451        // It must be a Short Write
    431452        this.len -= this.f.result;
     
    434455}
    435456
    436 int answer_sendfile( int pipe[2], int fd, int ans_fd, size_t fsize ) {
     457int answer_sendfile( int pipe[2], int fd, int ans_fd, size_t fsize, sendfile_stats_t & stats ) {
     458        stats.calls++;
    437459        #if defined(LINKED_IO)
    438460                char buffer[512];
     
    443465
    444466                RETRY_LOOP: for() {
     467                        stats.tries++;
    445468                        int have = need(header.res) + need(splice_in.res) + 1;
    446469                        int idx = 0;
     
    461484                        // we may need to kill the connection if it fails
    462485                        // If it already completed, this is a no-op
    463                         wait_and_process(splice_in);
     486                        wait_and_process(splice_in, stats);
    464487
    465488                        if(is_error(splice_in.res)) {
     
    469492
    470493                        // Process the other 2
    471                         wait_and_process(header);
    472                         wait_and_process(splice_out);
     494                        wait_and_process(header, stats);
     495                        wait_and_process(splice_out, stats);
    473496
    474497                        if(is_done(splice_out.res)) {
     
    490513                return len + fsize;
    491514        #else
     515                stats.tries++;
    492516                int ret = answer_header(fd, fsize);
    493517                if( ret < 0 ) { close(fd); return ret; }
  • benchmark/io/http/protocol.hfa

    r3a40df6 ref3c383  
    11#pragma once
     2
     3struct sendfile_stats_t;
    24
    35enum HttpCode {
     
    1820int answer_plaintext( int fd );
    1921int answer_empty( int fd );
    20 int answer_sendfile( int pipe[2], int fd, int ans_fd, size_t count );
     22int answer_sendfile( int pipe[2], int fd, int ans_fd, size_t count, struct sendfile_stats_t & );
    2123
    2224[HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len);
  • benchmark/io/http/worker.cfa

    r3a40df6 ref3c383  
    2323        this.pipe[1] = -1;
    2424        this.done = false;
     25
     26        this.stats.sendfile.calls = 0;
     27        this.stats.sendfile.tries = 0;
     28        this.stats.sendfile.header = 0;
     29        this.stats.sendfile.splcin = 0;
     30        this.stats.sendfile.splcot = 0;
     31        for(i; zipf_cnts) {
     32                this.stats.sendfile.avgrd[i].calls = 0;
     33                this.stats.sendfile.avgrd[i].bytes = 0;
     34        }
    2535}
    2636
     
    123133
    124134                        // Send the desired file
    125                         int ret = answer_sendfile( this.pipe, fd, ans_fd, count);
     135                        int ret = answer_sendfile( this.pipe, fd, ans_fd, count, this.stats.sendfile );
    126136                        if( ret == -ECONNRESET ) break REQUEST;
    127137
  • benchmark/io/http/worker.hfa

    r3a40df6 ref3c383  
    1111//=============================================================================================
    1212
     13extern const size_t zipf_sizes[];
     14enum { zipf_cnts = 36, };
     15
     16struct sendfile_stats_t {
     17        volatile uint64_t calls;
     18        volatile uint64_t tries;
     19        volatile uint64_t header;
     20        volatile uint64_t splcin;
     21        volatile uint64_t splcot;
     22        struct {
     23                volatile uint64_t calls;
     24                volatile uint64_t bytes;
     25        } avgrd[zipf_cnts];
     26};
     27
    1328thread Worker {
    1429        int pipe[2];
     
    1833        int flags;
    1934        volatile bool done;
     35        struct {
     36                sendfile_stats_t sendfile;
     37        } stats;
    2038};
    2139void ?{}( Worker & this);
Note: See TracChangeset for help on using the changeset viewer.