commit 33910b7e50032f267a0752e37a0dbe043f1cf350 Author: Richard Thier Date: Thu Mar 11 21:22:37 2021 +0100 project init diff --git a/README.md b/README.md new file mode 100644 index 0000000..2184aaa --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Magyar-sort + +Header-only library for my take on radix sorting in-place. + +Had this idea yesterday after watching "Creed"s video on youtube +first on cache locality and stuff and then just normal radix sort +(that I already know) in a recreational way. + +It struck me when watching the videos in this order that his counting +sort variant of course needs a separate array. He even says it would +be good if could be done in place... I was like... but hey! I can do +it in place! + +Biggest relevation was realizing that prefix sums will already tell +me from-to areas of sets in coded that were already sorted by its +first (radix-loop choosen) digit. I just need to keep the prefix sum +around in an untouched copy. + +Maybe better to do it on nibbles for better cache usage and do all +"digits" at once in a single big loop. Then algorithm is recursive: +first do biggest digit, then prefix sum1-2 will tell where digits +"areas" start and end. Between them we either recurse and do a small +radix on second char OR if the thing is small enough just do regular +sort on it and that is all... + +Also might be helpful to know starting digits are unused - small num +support? + +Will need to code it, has it on paper. Should be fast and cache-friendly! diff --git a/magyarsort.h b/magyarsort.h new file mode 100644 index 0000000..0424282 --- /dev/null +++ b/magyarsort.h @@ -0,0 +1,68 @@ +#ifndef MAGYAR_SORT_H +#define MAGYAR_SORT_H +/** + * single header lib: In-place, fast heavily modified and optimized radix sort. + * + * Only unsigned ints for now, but should be able to modify for int and float... + * This is the counting variant with smart changes (not per-bit). + * + * LICENCE: CC3 - look it up, you need to mention me but that is all + */ + +#include +#include + +namespace MagyarSort { + + // Only change these if you know what you are doing + // I use these because I want to see if nibbles are + // better or something... + // + // Bytes of nibbles only: + // - DIGIT_RANGE and BITS_PER_DIGIT should correspond + // - DIGITS should also correspond with the uint32_t + // - and DIGIT_RANGE should be 2^n value (16 or 256) + static constexpr int DIGITS = 4; // "helyiérték" + static constexpr int BITS_PER_DIGIT = 8; // "bit / helyiérték" + static constexpr int DIGIT_RANGE = 256; // "helyiérték állapottér" + + template + static inline uint32_t getDigit(uint32_t num) noexcept { + static constexpr int SHIFT = digitChoice * BITS_PER_DIGIT; + + uint32_t shifted = num >> SHIFT; + return shifted & DIGIT_RANGE; + } + + /** Sort the given array (in-place sorting) with the given size */ + inline void sort(uint32_t arr[], size_t size) noexcept { + // Holds "digit" occurences, prefix sums, whatevers + // First "DIGIT_RANGE" elem is for MSB "DIGITS", last is for LSB + static thread_local size_t radics[DIGITS * DIGIT_RANGE]; + for(int i = 0; i < (DIGITS * DIGIT_RANGE); ++i) { radics[i] = 0; } + + // Calculate occurences of digits + for(size_t i = 0; i < size; ++i) { + auto d0 = getDigit<0>(arr[i]); + auto d1 = getDigit<1>(arr[i]); + auto d2 = getDigit<2>(arr[i]); + auto d3 = getDigit<3>(arr[i]); + + ++radics[d0]; + ++radics[d1 + DIGIT_RANGE * 1]; + ++radics[d2 + DIGIT_RANGE * 2]; + ++radics[d3 + DIGIT_RANGE * 3]; + } + + // TODO: remove debug stuffz + for(size_t j = 0; j < DIGITS; ++j) { + printf("d%d: ", j); + for(size_t i = 0; i < DIGIT_RANGE; ++i) { + printf("%d,"); + } + printf("\n"); + } + } +}; + +#endif diff --git a/makefile b/makefile new file mode 100644 index 0000000..2eedbfb --- /dev/null +++ b/makefile @@ -0,0 +1,2 @@ +all: g++ test.cpp -o test.out +clean: rm test.out diff --git a/session.vim b/session.vim new file mode 100644 index 0000000..c4741c3 --- /dev/null +++ b/session.vim @@ -0,0 +1,647 @@ +let SessionLoad = 1 +if &cp | set nocp | endif +let s:cpo_save=&cpo +set cpo&vim +inoremap u +map Q gq +vmap gx NetrwBrowseXVis +nmap gx NetrwBrowseX +vnoremap NetrwBrowseXVis :call netrw#BrowseXVis() +nnoremap NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX())) +inoremap  u +let &cpo=s:cpo_save +unlet s:cpo_save +set background=dark +set backspace=indent,eol,start +set backupdir=~/.cache/vim/backup// +set directory=~/.cache/vim/swap// +set display=truncate +set fileencodings=ucs-bom,utf-8,default,latin1 +set helplang=hu +set history=200 +set incsearch +set langnoremap +set nolangremap +set mouse=a +set nrformats=bin,hex +set ruler +set scrolloff=5 +set showcmd +set suffixes=.bak,~,.o,.info,.swp,.aux,.bbl,.blg,.brf,.cb,.dvi,.idx,.ilg,.ind,.inx,.jpg,.log,.out,.png,.toc +set ttimeout +set ttimeoutlen=100 +set undodir=~/.cache/vim/undo// +set wildmenu +let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1 +let v:this_session=expand(":p") +silent only +silent tabonly +cd ~/munka/c_c++/magyarsort +if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == '' + let s:wipebuf = bufnr('%') +endif +set shortmess=aoO +argglobal +%argdel +$argadd README.md +$argadd makefile +$argadd magyarsort.h +$argadd test.cpp +set stal=2 +tabnew +tabnew +tabnew +tabrewind +edit README.md +set splitbelow splitright +set nosplitbelow +set nosplitright +wincmd t +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +argglobal +setlocal keymap= +setlocal noarabic +setlocal noautoindent +setlocal backupcopy= +setlocal balloonexpr= +setlocal nobinary +setlocal nobreakindent +setlocal breakindentopt= +setlocal bufhidden= +setlocal buflisted +setlocal buftype= +setlocal nocindent +setlocal cinkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal cinoptions= +setlocal cinwords=if,else,while,do,for,switch +setlocal colorcolumn= +setlocal comments=fb:*,fb:-,fb:+,n:> +setlocal commentstring= +setlocal complete=.,w,b,u,t,i +setlocal concealcursor= +setlocal conceallevel=0 +setlocal completefunc= +setlocal nocopyindent +setlocal cryptmethod= +setlocal nocursorbind +setlocal nocursorcolumn +setlocal nocursorline +setlocal cursorlineopt=both +setlocal define= +setlocal dictionary= +setlocal nodiff +setlocal equalprg= +setlocal errorformat= +setlocal noexpandtab +if &filetype != 'markdown' +setlocal filetype=markdown +endif +setlocal fixendofline +setlocal foldcolumn=0 +setlocal foldenable +setlocal foldexpr=0 +setlocal foldignore=# +setlocal foldlevel=0 +setlocal foldmarker={{{,}}} +setlocal foldmethod=manual +setlocal foldminlines=1 +setlocal foldnestmax=20 +setlocal foldtext=foldtext() +setlocal formatexpr= +setlocal formatoptions=tcqln +setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\|^[-*+]\\s\\+\\|^\\[^\\ze[^\\]]\\+\\]: +setlocal formatprg= +setlocal grepprg= +setlocal iminsert=0 +setlocal imsearch=-1 +setlocal include= +setlocal includeexpr= +setlocal indentexpr= +setlocal indentkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal noinfercase +setlocal iskeyword=@,48-57,_,192-255 +setlocal keywordprg= +setlocal nolinebreak +setlocal nolisp +setlocal lispwords= +setlocal nolist +setlocal makeencoding= +setlocal makeprg= +setlocal matchpairs=(:),{:},[:],<:> +setlocal modeline +setlocal modifiable +setlocal nrformats=bin,hex +set number +setlocal number +setlocal numberwidth=4 +setlocal omnifunc=htmlcomplete#CompleteTags +setlocal path= +setlocal nopreserveindent +setlocal nopreviewwindow +setlocal quoteescape=\\ +setlocal noreadonly +setlocal norelativenumber +setlocal norightleft +setlocal rightleftcmd=search +setlocal noscrollbind +setlocal scrolloff=-1 +setlocal shiftwidth=8 +setlocal noshortname +setlocal showbreak= +setlocal sidescrolloff=-1 +setlocal signcolumn=auto +setlocal nosmartindent +setlocal softtabstop=0 +setlocal nospell +setlocal spellcapcheck=[.?!]\\_[\\])'\"\ \ ]\\+ +setlocal spellfile= +setlocal spelllang=en +setlocal spelloptions= +setlocal statusline= +setlocal suffixesadd= +setlocal swapfile +setlocal synmaxcol=3000 +if &syntax != 'markdown' +setlocal syntax=markdown +endif +setlocal tabstop=8 +setlocal tagcase= +setlocal tagfunc= +setlocal tags= +setlocal termwinkey= +setlocal termwinscroll=10000 +setlocal termwinsize= +setlocal textwidth=0 +setlocal thesaurus= +setlocal noundofile +setlocal undolevels=-123456 +setlocal varsofttabstop= +setlocal vartabstop= +setlocal wincolor= +setlocal nowinfixheight +setlocal nowinfixwidth +setlocal wrap +setlocal wrapmargin=0 +silent! normal! zE +let &fdl = &fdl +let s:l = 29 - ((28 * winheight(0) + 28) / 56) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 29 +normal! 073| +tabnext +edit makefile +set splitbelow splitright +set nosplitbelow +set nosplitright +wincmd t +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +argglobal +2argu +balt README.md +setlocal keymap= +setlocal noarabic +setlocal noautoindent +setlocal backupcopy= +setlocal balloonexpr= +setlocal nobinary +setlocal nobreakindent +setlocal breakindentopt= +setlocal bufhidden= +setlocal buflisted +setlocal buftype= +setlocal nocindent +setlocal cinkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal cinoptions= +setlocal cinwords=if,else,while,do,for,switch +setlocal colorcolumn= +setlocal comments=sO:#\ -,mO:#\ \ ,b:# +setlocal commentstring=#\ %s +setlocal complete=.,w,b,u,t,i +setlocal concealcursor= +setlocal conceallevel=0 +setlocal completefunc= +setlocal nocopyindent +setlocal cryptmethod= +setlocal nocursorbind +setlocal nocursorcolumn +setlocal nocursorline +setlocal cursorlineopt=both +setlocal define= +setlocal dictionary= +setlocal nodiff +setlocal equalprg= +setlocal errorformat= +setlocal noexpandtab +if &filetype != 'make' +setlocal filetype=make +endif +setlocal fixendofline +setlocal foldcolumn=0 +setlocal foldenable +setlocal foldexpr=0 +setlocal foldignore=# +setlocal foldlevel=0 +setlocal foldmarker={{{,}}} +setlocal foldmethod=manual +setlocal foldminlines=1 +setlocal foldnestmax=20 +setlocal foldtext=foldtext() +setlocal formatexpr= +setlocal formatoptions=croql +setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s* +setlocal formatprg= +setlocal grepprg= +setlocal iminsert=0 +setlocal imsearch=-1 +setlocal include=^\\s*include +setlocal includeexpr= +setlocal indentexpr=GetMakeIndent() +setlocal indentkeys=!^F,o,O,<:>,=else,=endif +setlocal noinfercase +setlocal iskeyword=@,48-57,_,192-255 +setlocal keywordprg= +setlocal nolinebreak +setlocal nolisp +setlocal lispwords= +setlocal nolist +setlocal makeencoding= +setlocal makeprg= +setlocal matchpairs=(:),{:},[:] +setlocal modeline +setlocal modifiable +setlocal nrformats=bin,hex +set number +setlocal number +setlocal numberwidth=4 +setlocal omnifunc= +setlocal path= +setlocal nopreserveindent +setlocal nopreviewwindow +setlocal quoteescape=\\ +setlocal noreadonly +setlocal norelativenumber +setlocal norightleft +setlocal rightleftcmd=search +setlocal noscrollbind +setlocal scrolloff=-1 +setlocal shiftwidth=0 +setlocal noshortname +setlocal showbreak= +setlocal sidescrolloff=-1 +setlocal signcolumn=auto +setlocal nosmartindent +setlocal softtabstop=0 +setlocal nospell +setlocal spellcapcheck=[.?!]\\_[\\])'\"\ \ ]\\+ +setlocal spellfile= +setlocal spelllang=en +setlocal spelloptions= +setlocal statusline= +setlocal suffixesadd= +setlocal swapfile +setlocal synmaxcol=3000 +if &syntax != 'make' +setlocal syntax=make +endif +setlocal tabstop=8 +setlocal tagcase= +setlocal tagfunc= +setlocal tags= +setlocal termwinkey= +setlocal termwinscroll=10000 +setlocal termwinsize= +setlocal textwidth=0 +setlocal thesaurus= +setlocal noundofile +setlocal undolevels=-123456 +setlocal varsofttabstop= +setlocal vartabstop= +setlocal wincolor= +setlocal nowinfixheight +setlocal nowinfixwidth +setlocal wrap +setlocal wrapmargin=0 +silent! normal! zE +let &fdl = &fdl +let s:l = 1 - ((0 * winheight(0) + 28) / 56) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 1 +normal! 024| +tabnext +edit magyarsort.h +set splitbelow splitright +set nosplitbelow +set nosplitright +wincmd t +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +argglobal +3argu +balt README.md +setlocal keymap= +setlocal noarabic +setlocal noautoindent +setlocal backupcopy= +setlocal balloonexpr= +setlocal nobinary +setlocal nobreakindent +setlocal breakindentopt= +setlocal bufhidden= +setlocal buflisted +setlocal buftype= +setlocal cindent +setlocal cinkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal cinoptions= +setlocal cinwords=if,else,while,do,for,switch +setlocal colorcolumn= +setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// +setlocal commentstring=/*%s*/ +setlocal complete=.,w,b,u,t,i +setlocal concealcursor= +setlocal conceallevel=0 +setlocal completefunc= +setlocal nocopyindent +setlocal cryptmethod= +setlocal nocursorbind +setlocal nocursorcolumn +setlocal nocursorline +setlocal cursorlineopt=both +setlocal define=^\\s*#\\s*define +setlocal dictionary= +setlocal nodiff +setlocal equalprg= +setlocal errorformat= +setlocal noexpandtab +if &filetype != 'cpp' +setlocal filetype=cpp +endif +setlocal fixendofline +setlocal foldcolumn=0 +setlocal foldenable +setlocal foldexpr=0 +setlocal foldignore=# +setlocal foldlevel=0 +setlocal foldmarker={{{,}}} +setlocal foldmethod=manual +setlocal foldminlines=1 +setlocal foldnestmax=20 +setlocal foldtext=foldtext() +setlocal formatexpr= +setlocal formatoptions=croql +setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s* +setlocal formatprg= +setlocal grepprg= +setlocal iminsert=0 +setlocal imsearch=-1 +setlocal include=^\\s*#\\s*include +setlocal includeexpr= +setlocal indentexpr= +setlocal indentkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal noinfercase +setlocal iskeyword=@,48-57,_,192-255 +setlocal keywordprg= +setlocal nolinebreak +setlocal nolisp +setlocal lispwords= +setlocal nolist +setlocal makeencoding= +setlocal makeprg= +setlocal matchpairs=(:),{:},[:] +setlocal modeline +setlocal modifiable +setlocal nrformats=bin,hex +set number +setlocal number +setlocal numberwidth=4 +setlocal omnifunc=ccomplete#Complete +setlocal path= +setlocal nopreserveindent +setlocal nopreviewwindow +setlocal quoteescape=\\ +setlocal noreadonly +setlocal norelativenumber +setlocal norightleft +setlocal rightleftcmd=search +setlocal noscrollbind +setlocal scrolloff=-1 +setlocal shiftwidth=8 +setlocal noshortname +setlocal showbreak= +setlocal sidescrolloff=-1 +setlocal signcolumn=auto +setlocal nosmartindent +setlocal softtabstop=0 +setlocal nospell +setlocal spellcapcheck=[.?!]\\_[\\])'\"\ \ ]\\+ +setlocal spellfile= +setlocal spelllang=en +setlocal spelloptions= +setlocal statusline= +setlocal suffixesadd= +setlocal swapfile +setlocal synmaxcol=3000 +if &syntax != 'cpp' +setlocal syntax=cpp +endif +setlocal tabstop=8 +setlocal tagcase= +setlocal tagfunc= +setlocal tags= +setlocal termwinkey= +setlocal termwinscroll=10000 +setlocal termwinsize= +setlocal textwidth=0 +setlocal thesaurus= +setlocal noundofile +setlocal undolevels=-123456 +setlocal varsofttabstop= +setlocal vartabstop= +setlocal wincolor= +setlocal nowinfixheight +setlocal nowinfixwidth +setlocal wrap +setlocal wrapmargin=0 +silent! normal! zE +let &fdl = &fdl +let s:l = 63 - ((50 * winheight(0) + 28) / 56) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 63 +normal! 037| +tabnext +edit test.cpp +set splitbelow splitright +set nosplitbelow +set nosplitright +wincmd t +set winminheight=0 +set winheight=1 +set winminwidth=0 +set winwidth=1 +argglobal +4argu +balt README.md +setlocal keymap= +setlocal noarabic +setlocal noautoindent +setlocal backupcopy= +setlocal balloonexpr= +setlocal nobinary +setlocal nobreakindent +setlocal breakindentopt= +setlocal bufhidden= +setlocal buflisted +setlocal buftype= +setlocal cindent +setlocal cinkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal cinoptions= +setlocal cinwords=if,else,while,do,for,switch +setlocal colorcolumn= +setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// +setlocal commentstring=/*%s*/ +setlocal complete=.,w,b,u,t,i +setlocal concealcursor= +setlocal conceallevel=0 +setlocal completefunc= +setlocal nocopyindent +setlocal cryptmethod= +setlocal nocursorbind +setlocal nocursorcolumn +setlocal nocursorline +setlocal cursorlineopt=both +setlocal define=^\\s*#\\s*define +setlocal dictionary= +setlocal nodiff +setlocal equalprg= +setlocal errorformat= +setlocal noexpandtab +if &filetype != 'cpp' +setlocal filetype=cpp +endif +setlocal fixendofline +setlocal foldcolumn=0 +setlocal foldenable +setlocal foldexpr=0 +setlocal foldignore=# +setlocal foldlevel=0 +setlocal foldmarker={{{,}}} +setlocal foldmethod=manual +setlocal foldminlines=1 +setlocal foldnestmax=20 +setlocal foldtext=foldtext() +setlocal formatexpr= +setlocal formatoptions=croql +setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s* +setlocal formatprg= +setlocal grepprg= +setlocal iminsert=0 +setlocal imsearch=-1 +setlocal include=^\\s*#\\s*include +setlocal includeexpr= +setlocal indentexpr= +setlocal indentkeys=0{,0},0),0],:,0#,!^F,o,O,e +setlocal noinfercase +setlocal iskeyword=@,48-57,_,192-255 +setlocal keywordprg= +setlocal nolinebreak +setlocal nolisp +setlocal lispwords= +setlocal nolist +setlocal makeencoding= +setlocal makeprg= +setlocal matchpairs=(:),{:},[:] +setlocal modeline +setlocal modifiable +setlocal nrformats=bin,hex +set number +setlocal number +setlocal numberwidth=4 +setlocal omnifunc=ccomplete#Complete +setlocal path= +setlocal nopreserveindent +setlocal nopreviewwindow +setlocal quoteescape=\\ +setlocal noreadonly +setlocal norelativenumber +setlocal norightleft +setlocal rightleftcmd=search +setlocal noscrollbind +setlocal scrolloff=-1 +setlocal shiftwidth=8 +setlocal noshortname +setlocal showbreak= +setlocal sidescrolloff=-1 +setlocal signcolumn=auto +setlocal nosmartindent +setlocal softtabstop=0 +setlocal nospell +setlocal spellcapcheck=[.?!]\\_[\\])'\"\ \ ]\\+ +setlocal spellfile= +setlocal spelllang=en +setlocal spelloptions= +setlocal statusline= +setlocal suffixesadd= +setlocal swapfile +setlocal synmaxcol=3000 +if &syntax != 'cpp' +setlocal syntax=cpp +endif +setlocal tabstop=8 +setlocal tagcase= +setlocal tagfunc= +setlocal tags= +setlocal termwinkey= +setlocal termwinscroll=10000 +setlocal termwinsize= +setlocal textwidth=0 +setlocal thesaurus= +setlocal noundofile +setlocal undolevels=-123456 +setlocal varsofttabstop= +setlocal vartabstop= +setlocal wincolor= +setlocal nowinfixheight +setlocal nowinfixwidth +setlocal wrap +setlocal wrapmargin=0 +silent! normal! zE +let &fdl = &fdl +let s:l = 11 - ((10 * winheight(0) + 28) / 56) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 11 +normal! 028| +tabnext 3 +set stal=1 +badd +1 README.md +badd +0 makefile +badd +0 magyarsort.h +badd +0 test.cpp +if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 + silent exe 'bwipe ' . s:wipebuf +endif +unlet! s:wipebuf +set winheight=1 winwidth=20 shortmess=filnxtToOS +set winminheight=1 winminwidth=1 +let s:sx = expand(":p:r")."x.vim" +if filereadable(s:sx) + exe "source " . fnameescape(s:sx) +endif +let &g:so = s:so_save | let &g:siso = s:siso_save +doautoall SessionLoadPost +unlet SessionLoad +" vim: set ft=vim : diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..9d85bfd --- /dev/null +++ b/test.cpp @@ -0,0 +1,14 @@ +/* LICENCE: CC3 - look it up, you need to mention me but that is all */ + +#include +#include "magyarsort.h" + +int main() { + uint32_t smallArr[16] = { 0xFF, 0xFFFFFFFF, 0xAA000000, 10, 20, 200, 1234513, 1, 0, 65535, 1024*1024, 1026*16, 7, 8, 1, 0} + + MagyarSort::sort(smallArr, 16); + + // TODO: check, etc. + + return 0; +}