Skip to content

Instantly share code, notes, and snippets.

@PkmX
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PkmX/ea6ee1e0b56187006e80 to your computer and use it in GitHub Desktop.
Save PkmX/ea6ee1e0b56187006e80 to your computer and use it in GitHub Desktop.
// clang++/g++ -std=c++14 -Wall -Wextra -pedantic -O3 -march=native -fno-builtin
#include <cstring>
#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <x86intrin.h>
size_t avx2_strlen(const char* const s) {
static_assert(__AVX2__, "AVX2 is not supported");
const char* p = s;
while ((reinterpret_cast<uintptr_t>(p) & (sizeof(__m256i) - 1)) != 0) {
if (*p == 0) return p - s;
++p;
}
while (true) {
const int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(_mm256_load_si256(reinterpret_cast<const __m256i*>(p)), _mm256_setzero_si256()));
if (mask != 0) {
p += __builtin_ctz(mask);
break;
}
p += sizeof(__m256i);
}
return p - s;
}
size_t naive_strlen(const char* const s) {
const char* p = s;
while (*p != '\0') p++;
return p - s;
}
int main(const int argc, const char * const * const argv) {
const size_t n = argc >= 2 ? std::stoll(argv[1]) : 1000000000;
std::vector<char> v(n, '1');
v.back() = '\0';
const auto s = v.data();
const auto t1 = std::chrono::steady_clock::now();
std::cout << strlen(s) << std::endl;
const auto t2 = std::chrono::steady_clock::now();
std::cout << __builtin_strlen(s) << std::endl;
const auto t3 = std::chrono::steady_clock::now();
std::cout << naive_strlen(s) << std::endl;
const auto t4 = std::chrono::steady_clock::now();
std::cout << avx2_strlen(s) << std::endl;
const auto t5 = std::chrono::steady_clock::now();
const auto duration_in_ms = [](const auto t1, const auto t2) { return std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); };
std::cout << "glibc: " << duration_in_ms(t1, t2) << std::endl;
std::cout << "gcc builtin: " << duration_in_ms(t2, t3) << std::endl;
std::cout << "naive: " << duration_in_ms(t3, t4) << std::endl;
std::cout << "avx2: " << duration_in_ms(t4, t5) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment