The MariaDB code base contains quite a few implementations of CRC-32, some (or all?) of them using the CRC-32C polynomial. It would be good to create a uniform interface and remove any code duplication.
There is a crc32() function defined somewhere. Is it always the same, or does the bundled zlib use something else?
Mariabackup defines crc32_intel_pclmul(), which is enabled on AMD64 based on CPUID flags.
InnoDB defines its own things in ut_crc32_init(), most recently an interface to ARMv8 (AArch64, ARM64) crc32c_aarch64(). Apparently this function is not being used anywhere else.
MDEV-9872 introduced POWER crc32_vpmsum() that was later (in MariaDB Server 10.3) replaced with a C-based implementation.
A recent update of MyRocks introduced a duplicated implementation of crc32_vpmsum(), noticed by me due to build breakage (MDEV-19830).
At the very least, we should have a common CRC-32C implementation on all platforms and remove ut0crc32.cc from InnoDB code base. (Maybe it is not worth touching the code in the bundled zlib.)
If other CRC-32 polynomials are needed, then we should define a common interface for those as well.
Attachments
Issue Links
is blocked by
MDEV-22641Provide SIMD optimized wrapper for zlib crc32()
Closed
MDEV-22749Implement portable PCLMUL accelerated crc32() with Intel intrinsics
Closed
relates to
MDEV-27208Implement 2-ary CRC32() and the CRC32C() function
Closed
MDEV-9872Add common optimized CRC32 function interface
Closed
MDEV-19830MyRocks build fails on ppc64le: cinttypes: No such file or directory
An unified interface (with acceleration) for the zlib crc32() function will be introduced by MDEV-22641, using the function my_checksum().
After that, what remains to be done (in this task) is unifying the interface to CRC-32C (using the Castagnoli polynomial), which is used by MyRocks (RocksDB) and InnoDB. The RocksDB implementation is superior to InnoDB’s, because it can make use of the pclmul instruction, which apparently can outperform the SSE4.2 crc32 instructions that InnoDB is using.
The run-time check for the pclmul instruction should use the MDEV-22641 predicate crc32_pclmul_enabled().
Marko Mäkelä
added a comment - An unified interface (with acceleration) for the zlib crc32() function will be introduced by MDEV-22641 , using the function my_checksum() .
After that, what remains to be done (in this task) is unifying the interface to CRC-32C (using the Castagnoli polynomial), which is used by MyRocks (RocksDB) and InnoDB. The RocksDB implementation is superior to InnoDB’s, because it can make use of the pclmul instruction, which apparently can outperform the SSE4.2 crc32 instructions that InnoDB is using.
The run-time check for the pclmul instruction should use the MDEV-22641 predicate crc32_pclmul_enabled() .
Vladislav Vaintroub
added a comment - MyRocks uses both CRC32 instruction and pclmul , as described in https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/crc-iscsi-polynomial-crc32-instruction-paper.pdf
The following works at least starting with GCC 4.8.2 and clang 4.0.0. Note: I am only using this for illustration purposes; I am not suggesting to use any GCC-style built-in functions:
I think that using the target attribute is preferred to compiling the entire compilation unit with special flags. We do not want the compiler to accidentally use some SIMD instructions for unrelated parts of the code. This technique would also allow us to keep all code for different ISA dialects in the same compilation unit.
seems to be a dead end, because it is not supported on even the newest clang, and only supported starting with GCC 6.
Marko Mäkelä
added a comment - The following works at least starting with GCC 4.8.2 and clang 4.0.0. Note: I am only using this for illustration purposes; I am not suggesting to use any GCC-style built-in functions:
__attribute__((target( "sse4.2" )))
static unsigned crc32c_sse42(unsigned crc, unsigned data)
{
return __builtin_ia32_crc32qi(crc, data);
}
__attribute__((target( "pclmul" )))
static unsigned crc32c_pclmul(unsigned crc, unsigned data)
{
return 42; // FIXME: Use pclmul
}
unsigned crc32c(unsigned crc, unsigned data)
{
if (crc & 1) return crc32c_sse42(crc,data);
if (crc & 2) return crc32c_pclmul(crc,data);
return crc^data;
}
I think that using the target attribute is preferred to compiling the entire compilation unit with special flags. We do not want the compiler to accidentally use some SIMD instructions for unrelated parts of the code. This technique would also allow us to keep all code for different ISA dialects in the same compilation unit.
Side note: defining
__attribute__((target_clones( "sse4.2,pclmul,default" )))
seems to be a dead end, because it is not supported on even the newest clang , and only supported starting with GCC 6.
Marko Mäkelä
added a comment - Side note: The Galera library appears to include its own implementations:
strings /usr/lib/galera/libgalera_smm.so|grep CRC-32C
galera-4 (26.4.5-1)
CRC-32C: using hardware acceleration.
CRC-32C: using "slicing-by-8" algorithm.
unexpected CRC-32C implementation.
Using CRC-32C for message checksums.
after talking to marko, decided to push into 10.5, as the revised CRC32C implementation (CRC32+PCLMULQDQ) also gives nice speedup on for innodb checksum calculation on x64.
Nice speedup amounts to something like 2x faster, in my benchmarks with aligned 16K pages
Vladislav Vaintroub
added a comment - after talking to marko , decided to push into 10.5, as the revised CRC32C implementation (CRC32+PCLMULQDQ) also gives nice speedup on for innodb checksum calculation on x64.
Nice speedup amounts to something like 2x faster, in my benchmarks with aligned 16K pages
People
Vladislav Vaintroub
Marko Mäkelä
Votes:
0Vote for this issue
Watchers:
6Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":1027,"ttfb":207.69999980926514,"pageVisibility":"visible","entityId":77227,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":0.5,"journeyId":"0bb8c22a-c3a7-4c04-a596-a5701dafe3f6","navigationType":0,"readyForUser":1105.1999998092651,"redirectCount":0,"resourceLoadedEnd":980.1999998092651,"resourceLoadedStart":215.89999961853027,"resourceTiming":[{"duration":338.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":215.89999961853027,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":215.89999961853027,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":554.3999996185303,"responseStart":0,"secureConnectionStart":0},{"duration":338.3999996185303,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2cib/820016/12ta74/2bf333562ca6724060a9d5f1535471f6/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":216.30000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":216.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":554.6999998092651,"responseStart":0,"secureConnectionStart":0},{"duration":347.30000019073486,"initiatorType":"script","name":"https://jira.mariadb.org/s/0917945aaa57108d00c5076fea35e069-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":216.5,"connectEnd":216.5,"connectStart":216.5,"domainLookupEnd":216.5,"domainLookupStart":216.5,"fetchStart":216.5,"redirectEnd":0,"redirectStart":0,"requestStart":216.5,"responseEnd":563.8000001907349,"responseStart":563.8000001907349,"secureConnectionStart":216.5},{"duration":449.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/2d8175ec2fa4c816e8023260bd8c1786-CDN/lu2cib/820016/12ta74/2bf333562ca6724060a9d5f1535471f6/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":216.69999980926514,"connectEnd":216.69999980926514,"connectStart":216.69999980926514,"domainLookupEnd":216.69999980926514,"domainLookupStart":216.69999980926514,"fetchStart":216.69999980926514,"redirectEnd":0,"redirectStart":0,"requestStart":216.69999980926514,"responseEnd":666.3999996185303,"responseStart":666.3999996185303,"secureConnectionStart":216.69999980926514},{"duration":453.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/a9324d6758d385eb45c462685ad88f1d-CDN/lu2cib/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":217.19999980926514,"connectEnd":217.19999980926514,"connectStart":217.19999980926514,"domainLookupEnd":217.19999980926514,"domainLookupStart":217.19999980926514,"fetchStart":217.19999980926514,"redirectEnd":0,"redirectStart":0,"requestStart":217.19999980926514,"responseEnd":670.6999998092651,"responseStart":670.6999998092651,"secureConnectionStart":217.19999980926514},{"duration":453.6000003814697,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":217.5,"connectEnd":217.5,"connectStart":217.5,"domainLookupEnd":217.5,"domainLookupStart":217.5,"fetchStart":217.5,"redirectEnd":0,"redirectStart":0,"requestStart":217.5,"responseEnd":671.1000003814697,"responseStart":671.1000003814697,"secureConnectionStart":217.5},{"duration":453.8999996185303,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":217.60000038146973,"connectEnd":217.60000038146973,"connectStart":217.60000038146973,"domainLookupEnd":217.60000038146973,"domainLookupStart":217.60000038146973,"fetchStart":217.60000038146973,"redirectEnd":0,"redirectStart":0,"requestStart":217.60000038146973,"responseEnd":671.5,"responseStart":671.5,"secureConnectionStart":217.60000038146973},{"duration":490.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2cib/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":217.80000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":217.80000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":708.3000001907349,"responseStart":0,"secureConnectionStart":0},{"duration":454.1000003814697,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":218,"connectEnd":218,"connectStart":218,"domainLookupEnd":218,"domainLookupStart":218,"fetchStart":218,"redirectEnd":0,"redirectStart":0,"requestStart":218,"responseEnd":672.1000003814697,"responseStart":672.1000003814697,"secureConnectionStart":218},{"duration":490.30000019073486,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":218.19999980926514,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":218.19999980926514,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":708.5,"responseStart":0,"secureConnectionStart":0},{"duration":454.5999994277954,"initiatorType":"script","name":"https://jira.mariadb.org/s/5d5e8fe91fbc506585e83ea3b62ccc4b-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":218.30000019073486,"connectEnd":218.30000019073486,"connectStart":218.30000019073486,"domainLookupEnd":218.30000019073486,"domainLookupStart":218.30000019073486,"fetchStart":218.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":218.30000019073486,"responseEnd":672.8999996185303,"responseStart":672.8999996185303,"secureConnectionStart":218.30000019073486},{"duration":602.3999996185303,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":219.5,"connectEnd":219.5,"connectStart":219.5,"domainLookupEnd":219.5,"domainLookupStart":219.5,"fetchStart":219.5,"redirectEnd":0,"redirectStart":0,"requestStart":219.5,"responseEnd":821.8999996185303,"responseStart":821.8999996185303,"secureConnectionStart":219.5},{"duration":602.7999992370605,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":219.60000038146973,"connectEnd":219.60000038146973,"connectStart":219.60000038146973,"domainLookupEnd":219.60000038146973,"domainLookupStart":219.60000038146973,"fetchStart":219.60000038146973,"redirectEnd":0,"redirectStart":0,"requestStart":219.60000038146973,"responseEnd":822.3999996185303,"responseStart":822.3000001907349,"secureConnectionStart":219.60000038146973},{"duration":48,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":720,"connectEnd":720,"connectStart":720,"domainLookupEnd":720,"domainLookupStart":720,"fetchStart":720,"redirectEnd":0,"redirectStart":0,"requestStart":720,"responseEnd":768,"responseStart":768,"secureConnectionStart":720},{"duration":208.80000019073486,"initiatorType":"link","name":"https://jira.mariadb.org/s/d5715adaadd168a9002b108b2b039b50-CDN/lu2cib/820016/12ta74/be4b45e9cec53099498fa61c8b7acba4/_/download/contextbatch/css/jira.project.sidebar,-_super,-project.issue.navigator,-jira.general,-jira.browse.project,-jira.view.issue,-jira.global,-atl.general,-com.atlassian.jira.projects.sidebar.init/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":771.3999996185303,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":771.3999996185303,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":980.1999998092651,"responseStart":0,"secureConnectionStart":0}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":31,"responseStart":207,"responseEnd":210,"domLoading":213,"domInteractive":1174,"domContentLoadedEventStart":1174,"domContentLoadedEventEnd":1241,"domComplete":1507,"loadEventStart":1507,"loadEventEnd":1507,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":1142},{"name":"bigPipe.sidebar-id.end","time":1142.8000001907349},{"name":"bigPipe.activity-panel-pipe-id.start","time":1142.8999996185303},{"name":"bigPipe.activity-panel-pipe-id.end","time":1145.6999998092651},{"name":"activityTabFullyLoaded","time":1258.5}],"measures":[],"correlationId":"bead84b63cf4b1","effectiveType":"4g","downlink":9.9,"rtt":0,"serverDuration":111,"dbReadsTimeInMs":15,"dbConnsTimeInMs":23,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
An unified interface (with acceleration) for the zlib crc32() function will be introduced by
MDEV-22641, using the function my_checksum().After that, what remains to be done (in this task) is unifying the interface to CRC-32C (using the Castagnoli polynomial), which is used by MyRocks (RocksDB) and InnoDB. The RocksDB implementation is superior to InnoDB’s, because it can make use of the pclmul instruction, which apparently can outperform the SSE4.2 crc32 instructions that InnoDB is using.
The run-time check for the pclmul instruction should use the
MDEV-22641predicate crc32_pclmul_enabled().