Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
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;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
VPCLMULQDQ version for crc_fold_copy by guowangy · Pull Request #28 · intel/zlib · GitHub
Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' VPCLMULQDQ version for crc_fold_copy by guowangy · Pull Request #28 · intel/zlib · GitHub
Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

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

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' VPCLMULQDQ version for crc_fold_copy by guowangy · Pull Request #28 · intel/zlib · GitHub
Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' VPCLMULQDQ version for crc_fold_copy by guowangy · Pull Request #28 · intel/zlib · GitHub
Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' VPCLMULQDQ version for crc_fold_copy by guowangy · Pull Request #28 · intel/zlib · GitHub
Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

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

VPCLMULQDQ version for crc_fold_copy - #28

Open
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul
Open

VPCLMULQDQ version for crc_fold_copy#28
guowangy wants to merge 41 commits into
intel:masterfrom
guowangy:crc-fold-vpclmul

Conversation

@guowangy

Copy link
Copy Markdown

add VPCLMULQDQ version for crc_fold_copy

performance results in function level using make test:

crc_fold_copy testing:
PCLMUL time: 7.97ms
VPCLMULQDQ time: 4.45ms

The PR depends on #27

jtkukunasand others added 30 commits June 21, 2018 20:13
Adds check for SSE2, SSE4.2, and the PCLMULQDQ instructions.
Excessive loop unrolling is detrimental to performance. This patch
adds a preprocessor define, ADLER32_UNROLL_LESS, to reduce unrolling
factor from 16 to 8.
Updates configure script to set as default on x86
Adds a preprocessor define, CRC32_UNROLL_LESS, to reduce unrolling
factor from 8 to 4 for the crc32 calculation.
For systems supporting SSE4.2, use the crc32 intstruction as a fast hash
function.
We hash 4 bytes, instead of 3, for certain levels. This shortens the
hash chains, and also improves the quality of each hash entry.
Rather than copy the input data from strm->next_in into the window and
then compute the CRC, this patch combines these two steps into one. It
performs a SSE memory copy, while folding the data down in the SSE
registers. A final step is added, when we write the gzip trailer,
to reduce the 4 SSE registers to 32b.
Adds some extra padding bytes to the window to allow for SSE partial
writes.
In some (very rare) scenarios, the SIMD code in the `crc_folding` module
can perform out-of-bounds reads or writes, which could lead to GPF
crashes.
Here's the deal: when the `crc_fold_copy` function is called with a
non-zero `len` argument of less then 16, `src` is read through
`_mm_loadu_si128` which always reads 16 bytes. If the `src` pointer
points to a location which contains `len` bytes, but any of the `16 -
len` out-of-bounds bytes falls in unmapped memory, this operation will
trigger a GPF.
The same goes for the `dst` pointer when written to through
`_mm_storeu_si128`.
With this patch applied, the crash no longer occurs.
We first discovered this issue though Valgrind reporting an
out-of-bounds access while running a unit-test for some code derived
from `crc_fold_copy`. In general, the out-of-bounds read is not an issue
because reads only occur in sections which are definitely mapped
(assuming page size is a multiple of 16), and garbage bytes are ignored.
While giving this some more thought we realized for small `len` values
and `src` or `dst` pointers at a very specific place in the address
space can lead to GPFs.
- Minor tweaks to merge request by Jim Kukunas <james.t.kukunas@linux.intel.com>
- removed C11-isms
- use unaligned load
- better integrated w/ zlib (use zalign)
- removed full example code from commit msg
With deflate, the only destination for crc folding was the window, which
was guaranteed to have an extra 15B of padding (because we allocated it).
This padding allowed us to handle the partial store case (len < 16)
with a regular SSE store.
For inflate, this is no longer the case. For crc folding to be
efficient, it needs to operate on large chunks of the data each call.
For inflate, this means copying the decompressed data out to the
user-provided output buffer (moreso with our reorganized window). Since
it's user-provided, we don't have the padding guarantee and therefore
need to fallback to a slower method of handling partial length stores.
The deflate_quick strategy is designed to provide maximum
deflate performance.
deflate_quick achieves this through:
- only checking the first hash match
- using a small inline SSE4.2-optimized longest_match
- forcing a window size of 8K, and using a precomputed dist/len
table
- forcing the static Huffman tree and emitting codes immediately
instead of tallying
This patch changes the scope of flush_pending, bi_windup, and
static_ltree to ZLIB_INTERNAL and moves END_BLOCK, send_code,
put_short, and send_bits to deflate.h.
Updates the configure script to enable by default for x86. On systems
without SSE4.2, fallback is to deflate_fast strategy.
Fixesintel#6Fixesintel#8
From: Arjan van de Ven <arjan@linux.intel.com>
As the name suggests, the deflate_medium deflate strategy is designed
to provide an intermediate strategy between deflate_fast and deflate_slow.
After finding two adjacent matches, deflate_medium scans left from
the second match in order to determine whether a better match can be
formed.
Fixesintel#2
(Note emit_match() doesn't currently use the value at all.)
Fixesintel#4
…pilation.
Minor tweak by Jim Kukunas, dropping changes to configure script
This commit significantly improves inflate performance by reorganizing
the window buffer into a contiguous window and pending output buffer.
The goal of this layout is to reduce branching, improve cache locality,
and enable for the use of crc folding with gzip input.
The window buffer is allocated as a multiple of the user-selected window
size. In this commit, a factor of 4 is utilized.
The layout of the window buffer is divided into two sections. The first
section, window offset [0, wsize), is reserved for history that has
already been output. The second section, window offset [wsize, 4 * wsize),
is reserved for buffering pending output that hasn't been flushed to the
user's output buffer yet.
The history section grows downwards, towards the window offset of 0. The
pending output section grows upwards, towards the end of the buffer. As
a result, all of the possible distance/length data that may need to be
copied is contiguous. This removes the need to stitch together output
from 2 separate buffers.
In the case of gzip input, crc folding is used to copy the pending
output to the user's buffers.
Since the inflate optimizations depend on an efficient memcpy routine,
add an optimized version for platforms that don't have one.
This fixes an issue where a repeat sequence longer than 258 would be
encoded using longer distance values after the first match.
When we load new data into the window, we invalidate the next match, in
case the match would improve. In this case, the hash has already been
updated with this data, so when we look for a new match it will point
it back at itself. As a result, a literal is generated even when a
better match is available.
This avoids that by catching this case and ensuring we're looking at the
past.
Comment threadcrc_folding.c Outdated
Comment threadMakefile.in Outdated
Comment threadtest/perf_test.c Outdated
Comment threadMakefile.in Outdated
Comment threadcrc_folding_vpclmulqdq.c Outdated
@frankdjx

Copy link
Copy Markdown

Just some minor naming/format, others fine to me

nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 17, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 21, 2021
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Dec 28, 2021
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
nmoinvaz added a commit to nmoinvaz/zlib-ng that referenced this pull request Jan 8, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Dead2 pushed a commit to zlib-ng/zlib-ng that referenced this pull request Jan 9, 2022
Based on PR intel/zlib#28.
Co-authored-by: Wangyang Guo <wangyang.guo@intel.com>
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@guowangy@frankdjx@jtkukunas@NicolasT@mp15@vkvenkat