Я пытаюсь вычислить произведение точек между плавающим и битовым вектором наиболее эффективным образом на i7. В действительности, я делаю эту операцию на 128 или 256-мерных векторах, но для иллюстрации позвольте мне написать код для 64-мерных иллюстраций для иллюстрации проблемы:
// a has 64 elements. b is a bitvector of 64 dimensions.
float dot(float *restrict a, uint64_t b) {
float sum = 0;
for(int i=0; b && i<64; i++, b>>=1) {
if (b & 1) sum += a[i];
}
return sum;
}
Это работает, конечно же, но проблема в том, что это критическое время для всей программы (доходит до 95% процессорного времени в 50 минут), поэтому мне отчаянно нужно сделать это быстрее.
Мое предположение - ветвление выше - убийца игры (предотвращает выполнение вне порядка, вызывает плохое предсказание ветвления). Я не уверен, что векторные инструкции могут быть использованы и полезны здесь. Используя gcc 4.8 с -std = c99 -march = native -mtune = native -Ofast -funroll-loops, я в настоящее время получаю этот вывод
movl $4660, %edx
movl $5, %ecx
xorps %xmm0, %xmm0
.p2align 4,,10
.p2align 3
.L4:
testb $1, %cl
je .L2
addss (%rdx), %xmm0
.L2:
leaq 4(%rdx), %rax
shrq %rcx
testb $1, %cl
je .L8
addss 4(%rdx), %xmm0
.L8:
shrq %rcx
testb $1, %cl
je .L9
addss 4(%rax), %xmm0
.L9:
shrq %rcx
testb $1, %cl
je .L10
addss 8(%rax), %xmm0
.L10:
shrq %rcx
testb $1, %cl
je .L11
addss 12(%rax), %xmm0
.L11:
shrq %rcx
testb $1, %cl
je .L12
addss 16(%rax), %xmm0
.L12:
shrq %rcx
testb $1, %cl
je .L13
addss 20(%rax), %xmm0
.L13:
shrq %rcx
testb $1, %cl
je .L14
addss 24(%rax), %xmm0
.L14:
leaq 28(%rax), %rdx
shrq %rcx
cmpq $4916, %rdx
jne .L4
ret
Изменить Хорошо переписать данные (пока перестановка одинакова для всех параметров), порядок не имеет значения.
Мне интересно, есть ли что-то, что будет работать s > 3-кратной скоростью кода Криса Додда SSE2.
Новое примечание: код AVX/AVX2 также приветствуется!
Изменить 2 Учитывая битвектор, я должен умножить его на 128 (или 256, если он 256-бит) разных векторов float (так что также вполне возможно привлечь больше одного векторного вектора). Это весь процесс. Все, что ускорит весь процесс, также приветствуется!