Информация об изменениях

Сообщение Re[3]: Сумма элементов квадратной матрицы (школьная олимпиад от 13.01.2021 1:19

Изменено 13.01.2021 1:50 xma

Re[3]: Сумма элементов квадратной матрицы (школьная олимпиад
Здравствуйте, watchmaker, Вы писали:

W>Этот вставленный continue с условием внутри цикла полностью убьёт конвейер процессора.

W>В результате на случайных матрицах новый код будет работать куда медленнее старого. Просто из-за того, что такое условие будет постоянно неверно предсказываться и процессор будет занят не вычислениями, а борьбой с рандомными сбросами конвейера.

а ты профи, не ожидал — что sum1 в 15 раз медленнее sum0 при n=3000 ..

(sum0 на проце 10 летней давности 6 секунд), думаю что на 5900X — может и в 1.5-2 секунды уложиться .. (в однопотоке)

так что пусть обновят компы — на олимпиаде, какое то — лютое говно мамонта у них — там ..

код с таймерами — кому интересно, (ниже)

  Скрытый текст
int op = 0;
int sum0(int n, int* A) {
    int i, j, k, v, Aij, Ajk, Aki, s = 0; op = 0;
    for (i = 0;i < n;i++) {
        for (j = 0;j < n;j++) {
            Aij = A[i * n + j];op++;
            for (k = 0;k < n;k++) {
                Ajk = A[j * n + k]; Aki = A[k * n + i]; op += 2;
                v = Ajk < Aki ? Ajk : Aki;
                v = Aij < v ? Aij : v;
                s = s + v;
            }
        }
    }
    return s;
}
int sum1(int n, int* A) {
    int i, j, k, Cij, Aij, Ajk, Aki, s = 0; op = 0;
    for (i = 0;i < n;i++) {
        for (j = 0;j < n;j++) {
            if (i == j) continue;
            Aij = A[i * n + j]; op++; if (Aij <= 0) continue;
            for (Cij = k = 0;k < n;k++) {
                Ajk = A[j * n + k]; op++; if (Aij > Ajk) continue;
                Aki = A[k * n + i]; op++; if (Aij > Aki) continue;
                if (Aij < Ajk && Aij < Aki) Cij += 3;
                else if (Aij == Ajk && Aij < Aki) Cij += 2;
                else if (Aij <= Ajk && Aij == Aki) Cij++;
            }
            s += Aij * Cij;
        }
    }
    return s;
}

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#include <chrono>
#include <iostream>

int main(int argc, char const* argv[]) {
    enum { n = 3000 };
    int i, j, v, A[n * n];
    srand(time(0));

    for (i = 0;i < n;i++) {
        for (j = 0;j < n;j++) {
            v = rand() % 1000;
            A[i * n + j] = i == j ? 0 : v;
        }
    }

    //for (i = 0;i < n;i++) {
    //    for (j = 0;j < n;j++) printf("%4d", A[i * n + j]);
    //    printf("\n");
    //}

    //printf("sum0=%d", sum0(n, A));printf(" op=%d\n", op);
    //printf("sum1=%d", sum1(n, A));printf(" op=%d\n", op);

    auto start = std::chrono::high_resolution_clock::now();
    sum0(n, A);
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff = end - start;
    std::cout << "sum0("<< n << ", A),Time " << (diff.count() * 1000.0f) << " ms\n";

    start = std::chrono::high_resolution_clock::now();
    sum1(n, A);
    end = std::chrono::high_resolution_clock::now();
    diff = end - start;
    std::cout << "sum1(" << n << ", A),Time " << (diff.count() * 1000.0f) << " ms\n";

    getchar();

    return 0;
}
Re[3]: Сумма элементов квадратной матрицы (школьная олимпиад
Здравствуйте, watchmaker, Вы писали:

W>Этот вставленный continue с условием внутри цикла полностью убьёт конвейер процессора.

W>В результате на случайных матрицах новый код будет работать куда медленнее старого. Просто из-за того, что такое условие будет постоянно неверно предсказываться и процессор будет занят не вычислениями, а борьбой с рандомными сбросами конвейера.

а ты профи, не ожидал — что sum1 в 15 раз медленнее sum0 при n=3000 ..

(sum0 на проце 10 летней давности 6 секунд), думаю что на 5900X — может и в 1.5-2 секунды уложиться .. (в однопотоке)

так что пусть обновят компы — на олимпиаде, какое то — лютое говно мамонта у них — там ..

код с таймерами — кому интересно, (ниже)
[/s]