Няшная / Говнокод #12379 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
#include <stdio.h>
#include <malloc.h>
#include <sys/time.h>
#include <pthread.h>

#define MAXPRIME 10000001
char sieve[MAXPRIME];

typedef struct {
    int id, min, max, step;
    unsigned long long result;
} Task;

void primes() {
    printf("Searching prime numbers ...\n");
    sieve[0] = sieve[1] = 1;
    for (int i=2; i<MAXPRIME; i++)
        sieve[i] = 0;
    int i = 2;
    while (1) {
        while (i<MAXPRIME && sieve[i])
            i++;
        if (i >= MAXPRIME)
            break;
        for (int j=i*2; j<MAXPRIME; j+=i)
            sieve[j] = 1;
        i++;
    }
}

double utime() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec / 1000000.0;
}

unsigned long long calc(int thread, int min, int max, int step) {
    unsigned long long sum = 0;
    double start = utime();
    int nextshow = max+1;
    for (int n=max; n>=min; n-=step) {
        if (!sieve[n]) {
            sum += 1;
            continue;
        }
        if (n <= nextshow && n > min) {
            double elapsed = utime() - start, eta = elapsed/(max-n)*(n-min);
            printf("Thread %d: current=%d elapsed=%lfs eta=%lfh\n", thread, n, elapsed, eta/3600);
            nextshow = n < 10000 ? 0 : n - 10000;
        }
        int b;
        asm("movl %1, %%ecx\n"
            "1: dec %%ecx\n"
            "movl %%ecx, %%eax\n"
            "imull %%eax\n"
            "idivl %1\n"
            "cmpl %%ecx, %%edx\n"
            "jnz 1b\n"
            "movl %%ecx, %0"
            : "=g"(b)
            : "r"(n)
            : "%eax", "%ecx", "%edx");
        sum += b;
    }
    return sum;
}

void * thread(void *arg) {
    Task *task = arg;
    printf("Thread %d: working from %d to %d step %d\n", task->id, task->min, task->max, task->step);
    task->result = calc(task->id, task->min, task->max, task->step);
    printf("Thread %d: partial result is %llu\n", task->id, task->result);
    return NULL;
}

int main() {
    primes();

    int threads = 4;
    int max = 10000000;
    pthread_t tid[10];
    Task tasks[10];

    for (int i=0; i<threads; i++) {
        tasks[i].id = i;
        tasks[i].min = 1;
        tasks[i].max = max-i;
        tasks[i].step = threads;
        pthread_create(&tid[i], NULL, thread, &tasks[i]);
    }

    unsigned long long sum = 0;
    for (int i=0; i<threads; i++) {
        pthread_join(tid[i], NULL);
        sum += tasks[i].result;
    }

    printf("Result: %llu\n", sum);
    return 0;
}

Мое ужасное решение вот этой задачки: http://projecteuler.net/problem=407

В день, когда математика упорно не желает вспоминаться...
на помощь приходят брутальные и бессердечные ассемблер и мультитрединг.

model name: Pentium(R) Dual-Core CPU E5400 @ 2.70GHz
real 286m45.890s
user 545m44.926s

Запостил: bormand bormand, (Updated )

Комментарии (47) RSS

  • Пишу из кофе неподалёку от пляжа Мериса, острова Шри-Ланка. Тут перебои с Интернетом какие-то, но мне пофиг. С Новым Годом!
    Ответить
    • >Пишу из кофе неподалёку от пляжа Мериса, острова Шри-Ланка.
      ЗАВИДОВАТ

      >Тут перебои с Интернетом
      А, нет, отпустило.
      Ответить
      • Ничего на свету лучше нету,
        Чем сто мегабитов интернету!
        Ответить
      • > >Тут перебои с Интернетом
        > А, нет, отпустило.
        Это в основном из-за будущей жены. Она говорит, что я часто хожу на сранные сайты, например говнокод. Она считает его очень странным почему-то и говорит, чтобы я больше туда не ходил. Говорит, что у меня какая-то зависимость и что это очень плохо. Она ведь не права? Может мне её бросить?
        Ответить
        • >перебои с Интернетом
          >из-за будущей жены

          100Mbps-женщина перебивает интернет.

          И вообще, не нужно себя обманывать. Если ты один раз свозил девушку на Шри-Ланку на НГ, это еще не значит, что она будет тебе готовить и стирать носки. Тут без ожерелья с брелянтами не обойтись.
          Ответить
          • > Тут без ожерелья с брелянтами не обойтись.

            беги от неё!
            Ответить
      • А он вайфай из дома ловит. Потому и проблемы с интернетом...
        Ответить
  • админ мудак! неужели так трудно сделать ссылки кликабельными?
    Ответить
    • Неужели трудно поставить аддон или выделять? Чай, не в линксах сидишь.
      И, вообще, мы тут привыкли к хардкору, а ты тут лезешь со своим херомуставом в нашу часть.
      Ответить
      • Это написано специально для админа! Какого ты лезешь вообще? Хардкорщик хренов...
        Ответить
        • Может быть, я на самом деле виртуал админа? Или нет, rat4. Совсем запутался, короче, не помню. Помню - чей-то.
          Ответить
    • Одно из преимуществ регистрации: у зарегистрированных пользователей ссылки кликабельны и они могут читать
      скрытый текст:
      Для просмотра скрытого текста - войдите или зарегистрируйтесь.
      Ответить
        • Ньюфаг... Парни, а классный анекдот модер затравил скрытым текстом, да?

          А король-то голый...
          Ответить
          • >классный анекдот
            Не анекдот это, а реальный случай. К сожалению.
            Ответить
        • Ну хоть ссылки-то работают? Подозреваю всё дело в кукисах.
          Ответить
          • Ссылки-то работают. У меня же id < 2k. А кукис браузером я уже два раза почистил.
            Ответить
            • А что id, в формуле рассчёта кармы не учитывается id. В пункте 2.4.5 правил дана же формула. Если ссылки не работают, могу скинуть в личку.
              Ответить
        • Ссылки кликабельны только при карме >= 100. Так написано в правилах.
          Ответить
          • Ну да. Там и про отображение скрытых текстов написано.
            Ответить
          • >кликабельны только при карме >= 100.
            Это само собой. Оно сохраняется в куках.
            Когда карма превысила порог а ссылки не работают, то нужно просто почистить куки.
            Потому иногда проблемы с сессиями. Пользователя может разлогинить. Например когда карма упала ниже порога.

            Да что там. Вновь прибывшим даже писать комментарии неделю нельзя. Оттуда же.
            Ответить
            • Ещё пообсуждать чутка, и родятся правила поведения ГК 2.0
              Ответить
      • $регистрации
        fixed
        Но ссылки когда есть сессия, работают, да.
        Ответить
  • @siteDevs: добавьте возможность поставить шрифтом выбранного говнокода Comic Sans, ибо ваистену!
    Ответить
  • И что? Этот асмовысер сколько % производительности прибавляет?
    Ответить
    • Если сравнивать с тем что там было до этого:
      for (int b=n-1; ; --b) {
          long long lb = b;
          if ((lb*lb) % n == b) {
              sum += b;
              break;
          }
      }
      то асм быстрее в 2.8 раза. Гцц вместо дива какого-то хуя втыкает вызов __moddi3, который и убивает всю производительность. А ждать 15 часов вместо 5 меня не особо прикалывало, вот и переписал на асме.
      Ответить
      • Не понимаю, почему втыкается этот __moddi3, судя по докам он нужен для деления 64-битных на 64-битные на 32-битной платформе. Но тут то я делю на 32-битное число, поэтому должен проканать и обычный div/idiv...
        Ответить
        • Щас у себя посмотрел. Если собирать под 32 бит, то он вставляет __moddi3 и прочую вакханалию.
          Если 64 бит. То
          imulq	%rax, %rax
          	movslq	-40(%rbp), %rcx
          	cqto
          	idivq	%rcx
          	movslq	-60(%rbp), %rax
          	cmpq	%rax, %rdx
          	jne	LBB2_13

          5 часов ждать не стал, как побыстрее оценить?)
          Searching prime numbers ...
          Thread 0: working from 1 to 10000000 step 4
          Thread 0: current=10000000 elapsed=0.000001s eta=infh
          Thread 1: working from 1 to 9999999 step 4
          Thread 1: current=9999999 elapsed=0.000001s eta=infh
          Thread 2: working from 1 to 9999998 step 4
          Thread 2: current=9999998 elapsed=0.000001s eta=infh
          Thread 3: working from 1 to 9999997 step 4
          Thread 3: current=9999997 elapsed=0.000001s eta=infh
          Thread 0: current=9990000 elapsed=37.571820s eta=10.426179h
          Thread 2: current=9989998 elapsed=45.755806s eta=12.697232h
          Thread 3: current=9989997 elapsed=47.328907s eta=13.133766h
          Thread 1: current=9989999 elapsed=49.395768s eta=13.707323h
          Thread 0: current=9980000 elapsed=74.303516s eta=10.299292h
          Thread 2: current=9979998 elapsed=90.654717s eta=12.565747h
          Thread 3: current=9979997 elapsed=95.896572s eta=13.292325h
          Thread 1: current=9979999 elapsed=98.456737s eta=13.647195h
          Ответить
          • Ну вот eta часов 10-13, значит где-то за 5 управится, у меня примерно в этом районе и показывало. Быстрее или медленнее той асмовставки оно всяко не будет работать, т.к. количество делений по идее будет таким же, а все остальное - копейки.

            > Если 64 бит. То
            Хороший код получился. Давно хотел сменить ось на 64битную. Видимо настало время.
            Ответить
            • > Давно хотел сменить ось на 64битную. Видимо настало время.
              да, срочно переходим на UTCv6, где в сутках 64 часа
              Ответить
      • А так?
        (int)((((long long) b)*((long long) b))%n);

        Я точно знаю что гцц правильно делает
        (int)((((long long) b)*((long long) b))>>32);

        так что может ты записал не так?
        Ответить
        • Ну вот со сдвигом 100% получается. А делить не хочет. Я и signed и unsigned во всех сочетаниях поперевтыкал. Все равно этот __moddi3 или __umoddi3, в который делителем приходит 64 битное число, у которого в старших разрядах намертво забит 0.
          Ответить
          • С делением да, странно. Делитель пробовал по-разному делать, и в int и в long long?
            Эх а вот в Форте есть готовый оператор */ для такой фигни - умножить и поделить, имея промежуточный результат двойной длины.
            А в Аде есть фиксированная запятая, она тут как-то должна помочь, мне кажется.
            Ответить
            • > Делитель пробовал по-разному делать, и в int и в long long?
              Да, конечно.

              > в Форте есть готовый оператор */ для такой фигни
              Да, именно такой функции и не хватает. Можно конечно ее запилить в виде макроса на асме под важные платформы, а на остальных оставить костылик с кастом в int64 перед умножением.
              Ответить
        • P.S. Понятно, что в стандартах c/c++ написано, что перед операцией оба операнда приводятся к одному типу. Но в данном случае компилеру заведомо известно, что число 32битное, и он мог бы сгенерить сокращенный код без полноценного 64битного деления... хбз почему так не сделали, может быть я еще что-то упускаю..
          Ответить

Добавить комментарий

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8