avoid indirection when getting the metrics ordered

This commit is contained in:
Ahmet Inan 2024-03-07 18:13:15 +01:00
commit a80f5cd532
3 changed files with 38 additions and 19 deletions

View file

@ -7,7 +7,6 @@ Copyright 2020 Ahmet Inan <inan@aicodix.de>
#pragma once
#include "simd.hh"
#include "sort.hh"
namespace CODE {

View file

@ -52,23 +52,33 @@ struct PolarListNode<TYPE, 0>
static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft)
{
TYPE sft = soft[1];
SIMD<PATH, 2*TYPE::SIZE> fork;
PATH fork[2*TYPE::SIZE];
for (int k = 0; k < TYPE::SIZE; ++k)
fork.v[2*k] = fork.v[2*k+1] = metric[k];
fork[2*k] = fork[2*k+1] = metric[k];
for (int k = 0; k < TYPE::SIZE; ++k)
if (sft.v[k] < 0)
fork.v[2*k] -= sft.v[k];
fork[2*k] -= sft.v[k];
else
fork.v[2*k+1] += sft.v[k];
auto perm = vorder(fork);
fork[2*k+1] += sft.v[k];
int perm[2*TYPE::SIZE];
perm[0] = 0;
for (int i = 1, j; i < 2*TYPE::SIZE; ++i) {
PATH t = fork[i];
for (j = i; j > 0 && fork[j-1] > t; --j) {
fork[j] = fork[j-1];
perm[j] = perm[j-1];
}
fork[j] = t;
perm[j] = i;
}
for (int k = 0; k < TYPE::SIZE; ++k)
metric[k] = fork.v[perm.v[k]];
metric[k] = fork[k];
MAP map;
for (int k = 0; k < TYPE::SIZE; ++k)
map.v[k] = perm.v[k] >> 1;
map.v[k] = perm[k] >> 1;
TYPE hrd;
for (int k = 0; k < TYPE::SIZE; ++k)
hrd.v[k] = 1 - 2 * (perm.v[k] & 1);
hrd.v[k] = 1 - 2 * (perm[k] & 1);
message[*count] = hrd;
maps[*count] = map;
++*count;

View file

@ -100,32 +100,42 @@ struct PolarParityNode<TYPE, 0>
static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *index, TYPE *hard, TYPE *soft, TYPE *parity, int *count, int stride)
{
TYPE sft = soft[1];
SIMD<PATH, 2*TYPE::SIZE> fork;
PATH fork[2*TYPE::SIZE];
for (int k = 0; k < TYPE::SIZE; ++k)
fork.v[2*k] = fork.v[2*k+1] = metric[k];
fork[2*k] = fork[2*k+1] = metric[k];
for (int k = 0; k < TYPE::SIZE; ++k)
if (sft.v[k] < 0)
fork.v[2*k] -= sft.v[k];
fork[2*k] -= sft.v[k];
else
fork.v[2*k+1] += sft.v[k];
fork[2*k+1] += sft.v[k];
if (*count == 0) {
TYPE chk = *parity;
*parity = PH::one();
for (int k = 0; k < TYPE::SIZE; ++k)
if (chk.v[k] < 0)
fork.v[2*k] = 1000000;
fork[2*k] = 1000000;
else
fork.v[2*k+1] = 1000000;
fork[2*k+1] = 1000000;
}
int perm[2*TYPE::SIZE];
perm[0] = 0;
for (int i = 1, j; i < 2*TYPE::SIZE; ++i) {
PATH t = fork[i];
for (j = i; j > 0 && fork[j-1] > t; --j) {
fork[j] = fork[j-1];
perm[j] = perm[j-1];
}
fork[j] = t;
perm[j] = i;
}
auto perm = vorder(fork);
for (int k = 0; k < TYPE::SIZE; ++k)
metric[k] = fork.v[perm.v[k]];
metric[k] = fork[k];
MAP map;
for (int k = 0; k < TYPE::SIZE; ++k)
map.v[k] = perm.v[k] >> 1;
map.v[k] = perm[k] >> 1;
TYPE hrd;
for (int k = 0; k < TYPE::SIZE; ++k)
hrd.v[k] = 1 - 2 * (perm.v[k] & 1);
hrd.v[k] = 1 - 2 * (perm[k] & 1);
if (*count) {
message[*index] = hrd;
*parity = PH::qmul(vshuf(*parity, map), hrd);