Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parallel Stable Sort

This repository contains a parallel stable sort using arbitrary extra memory written in C++. It combines classic mergesort, insertion sort and an in-place merging method described in [1]. It is able to utilize varying sizes of element buffers ranging from no buffer at all to the classic buffer with same length as input (or half the input length in sequential version). Though it degrades to using no buffer if specified length would not bring a speedup (generally at least a fraction of $\sqrt{n}$ is needed, where $n$ is the length of the input). The code is parallelized using OpenMP.

Performance

What follows is a brief showcase of what performance to expect. Tests were done on a machine with 2x Xeon E5-2620 v2 (12 cores, 24 threads) using a randomly sorted array of $10^8$ integers.

Single thread performance compared with std::stable_sort from STL:

Algorithm:Out-place mergesortstd::stable_sortIn-place mergesort
Time:9.698 s10.750 s15.692 s

Sequential time based on buffer size:

Parallel time using 24 threads based on buffer size (x stands for minimum buffer size to be used by 1 thread):

Out-place mergesort parallel speedup:

In-place mergesort parallel speedup:

Usage Example

#include"hybridsort.h"
…
std::vector<int> vec;
…
HybridSort(vec.begin(), vec.end()); // by default sorts with extra buffer of elements with length equal to end - beginHybridSort(vec.begin(), vec.end(), compare_func); // sorts while using compare_func to compare elementsHybridSort(vec.begin(), vec.end(), std::less<>(), 0); // sorts with no extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), -1LL); // sorts with maximum extra memory bufferHybridSort(vec.begin(), vec.end(), std::less<>(), 1000, 4); // sorts with a buffer of 1000 elements using 4 threads

References

[1] Kim, PS., Kutzner, A. (2008). Ratio Based Stable In-Place Merging. In: Agrawal, M., Du, D., Duan, Z., Li, A. (eds) Theory and Applications of Models of Computation. TAMC 2008. Lecture Notes in Computer Science, vol 4978. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-79228-4_22