Проблема:
Я пытаюсь понять, как написать код (C preffered, ASM, только если нет другого решения), который сделает прогностическое отклонение ветвления в 50% случаев.
Таким образом, это должна быть часть кода, которая "является imune" для оптимизаций компилятора, связанных с ветвлением, а также все предсказания ветвления HW не должны превышать 50% (бросая монету). Еще большая проблема заключается в том, чтобы запустить код на архитектуре нескольких процессоров и получить то же 50% -ное отклонение.
Мне удалось написать код, который идет на 47% -ный коэффициент пропускания ветвей на платформе x86. Я подозреваю, что пропавшие могут получить 3%:
- Накладные расходы на запуск программы, которые имеют ветвление в ней (очень маленький)
 - Накладные расходы профилировщика - в основном для каждого счетчика считывается прерывание, поэтому это может добавить дополнительные предсказуемые ветки.
 - Системные вызовы, выполняющиеся в фоновом режиме, содержащие циклы и предсказуемое ветвление
 
Я написал свой собственный генератор случайных чисел, чтобы избежать обращения к rand, реализация которого может иметь скрытые предсказуемые ветки. Он также может использовать rdrand, когда он доступен. Задержка не имеет значения для меня.
Вопросы:
- Могу ли я сделать лучше, чем моя версия кода? Лучше означает получение более раннего отклонения от ветки и одинаковые результаты для всех архитектур процессора.
 - Может ли этот код использоваться? Что это значит?
 
Код:
#include <stdio.h>
#include <time.h>
#define RDRAND
#define LCG_A   1103515245
#define LCG_C   22345
#define LCG_M   2147483648
#define ULL64   unsigned long long
ULL64 generated;
ULL64 rand_lcg(ULL64 seed)
{
#ifdef RDRAND
    ULL64 result = 0;
    asm volatile ("rdrand %0;" : "=r" (result));
    return result;
#else
    return (LCG_A * seed + LCG_C) % LCG_M;
#endif
}
ULL64 rand_rec1()
{
    generated = rand_lcg(generated) % 1024;
    if (generated < 512)
        return generated;
    else return rand_rec1();
}
ULL64 rand_rec2()
{
    generated = rand_lcg(generated) % 1024;
    if (!(generated >= 512))
        return generated;
    else return rand_rec2();
}
#define BROP(num, sum)                  \
    num = rand_lcg(generated);          \
    asm volatile("": : :"memory");      \
    if (num % 2)                        \
        sum += rand_rec1();             \
    else                                \
        sum -= rand_rec2();
#define BROP5(num, sum)     BROP(num, sum) BROP(num, sum) BROP(num, sum) BROP(num, sum) BROP(num, sum)
#define BROP25(num, sum)    BROP5(num, sum) BROP5(num, sum) BROP5(num, sum) BROP5(num, sum) BROP5(num, sum)
#define BROP100(num, sum)   BROP25(num, sum) BROP25(num, sum) BROP25(num, sum) BROP25(num, sum)
int main()
{
    int i = 0;
    int iterations = 500000;    
    ULL64 num = 0;
    ULL64 sum = 0;
    generated = rand_lcg(0) % 54321;
    for (i = 0; i < iterations; i++)
    {
        BROP100(num, sum);
        // ... repeat the line above 10 times
    }
    printf("Sum = %llu\n", sum);
}
Обновить v1:
Следуя предложению usr, я сгенерировал различные шаблоны, изменив параметр LCG_C из командной строки в script. Я смог перейти на прохождение BP на 49,67%. Этого достаточно для моей цели, и у меня есть методология для создания этого на разных архитектурах.