Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Чтобы подавить элиминацию цикла, делай в цикле
__asm__ __volatile__ ("");Но только с GCC прокатит. Clang и это оптимизирует. А результат функции
if (x == func(a, b)) {
__asm__ __volatile__ ("");
}Но блин. Всё равно какие-то из циклов получаются на удивление короткими начиная с 02. Я делал сложение результата я с глобальной переменной, а входные данные генерировал рандомом во время работы. Но всё равно не уверен в результатах с -O3 и -Ofast
for (i=0;i<l;i+=4){
if ((str[i] >= '0') && (str[i] <= '9')) return (i);
if ((str[i+1] >= '0') && (str[i+1] <= '9')) return (i+1);
if ((str[i+2] >= '0') && (str[i+2] <= '9')) return (i+2);
if ((str[i+3] >= '0') && (str[i+3] <= '9')) return (i+3);
}
#include <intrin.h>
const char* find_digit(const char* str) {
static const __m128i str_mask[16] = {
_mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x000000FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x000000FF, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x00FFFFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x0000FFFF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x000000FF, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x00000000, 0x00FFFFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x00000000, 0x0000FFFF),
_mm_set_epi32(0x00000000, 0x00000000, 0x00000000, 0x000000FF)
};
static const __m128i str_offset = _mm_set1_epi8(127 - '9');
static const __m128i str_threshold = _mm_set1_epi8(127 - 10);
const size_t str_misalignment = ((size_t)str) & ((size_t)15);
const __m128i* str_aligned = (const __m128i*)(((size_t)str) - str_misalignment);
__m128i str_vector = _mm_load_si128(str_aligned);
str_vector = _mm_and_si128(str_vector, str_mask[str_misalignment]);
str_vector = _mm_add_epi8(str_vector, str_offset);
int str_bitmask = _mm_movemask_epi8(_mm_cmpgt_epi8(str_vector, str_threshold));
unsigned long index;
_BitScanForward(&index, str_bitmask);
while (str_bitmask == 0) {
str_aligned += 1;
str_vector = _mm_load_si128(str_aligned);
str_vector = _mm_add_epi8(str_vector, str_offset);
str_bitmask = _mm_movemask_epi8(_mm_cmpgt_epi8(str_vector, str_threshold));
_BitScanForward(&index, str_bitmask);
}
return ((const char*)str_aligned) + index;
}
// счастливой отладки
Оптимизация скорости исполнения кода