Last active
August 29, 2015 14:20
-
-
Save PkmX/ea6ee1e0b56187006e80 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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