mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
scrolling: optimize row access by assuming number of rows is a power of 2
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In terms of instructions, this means a fast 'and' instead of a slow 'div'. Further optimize scrolling by: * not double-initializing empty rows. Previously, grid_row_alloc() called calloc(), which was then followed by a memset() when scrolling. This is of course unnecessary. * Don't loop the entire set of visible rows (this was done to ensure all visible rows had been allocated, and to prefetch the cell contents). This isn't necessary; only newly pulled in rows can be NULL. For now, don't prefetch at all.
This commit is contained in:
parent
f0663c951e
commit
7c7720a3ab
5 changed files with 107 additions and 56 deletions
40
grid.h
40
grid.h
|
|
@ -3,25 +3,37 @@
|
|||
#include <stddef.h>
|
||||
#include "terminal.h"
|
||||
|
||||
void grid_swap_row(struct grid *grid, int row_a, int row_b);
|
||||
struct row *grid_row_alloc(int cols);
|
||||
void grid_swap_row(struct grid *grid, int row_a, int row_b, bool initialize);
|
||||
struct row *grid_row_alloc(int cols, bool initialize);
|
||||
void grid_row_free(struct row *row);
|
||||
|
||||
static inline struct row *
|
||||
_grid_row_maybe_alloc(struct grid *grid, int row_no, bool alloc_if_null)
|
||||
{
|
||||
assert(grid->offset >= 0);
|
||||
|
||||
int real_row = (grid->offset + row_no) & (grid->num_rows - 1);
|
||||
struct row *row = grid->rows[real_row];
|
||||
|
||||
if (row == NULL && alloc_if_null) {
|
||||
row = grid_row_alloc(grid->num_cols, false);
|
||||
grid->rows[real_row] = row;
|
||||
}
|
||||
|
||||
assert(row != NULL);
|
||||
return row;
|
||||
}
|
||||
|
||||
static inline struct row *
|
||||
grid_row(struct grid *grid, int row_no)
|
||||
{
|
||||
assert(grid->offset >= 0);
|
||||
return _grid_row_maybe_alloc(grid, row_no, false);
|
||||
}
|
||||
|
||||
int real_row = (grid->offset + row_no + grid->num_rows) % grid->num_rows;
|
||||
struct row *row = grid->rows[real_row];
|
||||
|
||||
if (row == NULL) {
|
||||
row = grid_row_alloc(grid->num_cols);
|
||||
grid->rows[real_row] = row;
|
||||
}
|
||||
|
||||
__builtin_prefetch(row->cells, 1, 3);
|
||||
return row;
|
||||
static inline struct row *
|
||||
grid_row_and_alloc(struct grid *grid, int row_no)
|
||||
{
|
||||
return _grid_row_maybe_alloc(grid, row_no, true);
|
||||
}
|
||||
|
||||
static inline struct row *
|
||||
|
|
@ -29,7 +41,7 @@ grid_row_in_view(struct grid *grid, int row_no)
|
|||
{
|
||||
assert(grid->view >= 0);
|
||||
|
||||
int real_row = (grid->view + row_no + grid->num_rows) % grid->num_rows;
|
||||
int real_row = (grid->view + row_no) & (grid->num_rows - 1);
|
||||
struct row *row = grid->rows[real_row];
|
||||
|
||||
assert(row != NULL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue