пример кода гиперпоточности

Есть ли пример кода, иллюстрирующий производительность Intel Hyperthreading? Доступен ли он вообще из пользовательского пространства, или этот ЦП делает всю работу прозрачно для программиста? Это для C, Linux.


person Dervin Thunk    schedule 16.09.2013    source источник


Ответы (1)


Производительность гиперпоточности зависит от многих факторов и ее трудно оценить.

Просто кратко объясните Hyperthreading:

  • Каждое ядро ​​имеет более одного набора регистров, но не имеет дополнительных исполнительных блоков.
  • Гиперпотоки распределяются более или менее равномерно

Таким образом, вы действительно получаете дополнительную производительность от гиперпотоков только в том случае, если два потока, работающих на одном ядре, используют разные исполнительные блоки, и каждый поток сам по себе будет иметь слишком много зависимостей от данных. Например, один поток выполняет только операции с целыми числами, а другой — только с плавающей запятой. Затем вы можете увидеть дополнительную производительность, потому что вы используете больше исполнительных единиц за цикл.

Но это, в свою очередь, зависит от того, как ваша ОС распределяет потоки по гиперпотокам. С точки зрения ОС каждый гиперпоток является логическим процессором. Так что это полностью зависит от планировщика, что туда помещать и когда.

На практике гиперпотоки дадут вам не более 10-20% дополнительной производительности. На нашем HPC мы отключили их (в основном по причинам лицензирования).

Чтобы ответить на ваш актуальный вопрос: вы не можете самостоятельно развертывать код в гиперпотоках. ОС сделает это за вас. Вы можете установить сходство планирования для ваших пользовательских потоков, но все еще зависит от планировщика, чтобы фактически развернуть ваши потоки. Это делается прозрачно для программиста. Хороший планировщик будет равномерно развертывать ваш код сначала на ядрах и прибегать к гиперпотокам только в том случае, если все ядра заняты.

Пользовательский coltrol syscalls, который вы ищете, это sched_setaffinity и pthread_setaffinity_np.

В следующем примере кода будут развернуты два потока на логических ЦП 0 и 1, которые будут соответствовать двум гиперпотокам на первом логическом ядре первого сокета, если гиперпотоки включены. Тем не менее, это зависит от планировщика, чтобы фактически поместить их туда. Если эти гиперпотоки заняты, ваш код будет спать:

#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#include <stdlib.h>

void * my_thread(intptr_t cput_o_run_on) {
    cpuset_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(cput_o_run_on, &cpuset);

    pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);

    // force a rescheduling
    sched_yield();

    // do something useful

    return NULL;
}

int main() {
    pthread_t thread;

    pthread_create(&thread, NULL, my_thread, 0);
    pthread_create(&thread, NULL, my_thread, 1);

    for (;;);

    return 0;
}
person Sergey L.    schedule 16.09.2013