Наиболее быстрый способ передачи данных потокам-потребителям

Наиболее быстрый способ передачи данных потокам-потребителям

19.02.2014 05:44:04 Просмотров 24 Источник

Помимо рассмотренного в исследовании способа(№1) передачи данных в поток-потребитель с использованием переменной состояния и мьютекса, теоретически можно использовать еще пару:
№2 : запись данных(или указателя на них) в неименованный канал в потоке производителе, и их чтение в потоке потребителе в цикле с select();
№3 : использование очередей сообщений;
Я пыталась сравнить по скорости выполнения первые 2, получилась незначительная разница в пользу первого варианта, но результат меня все равно не устроил. Пользоваться очередями пока не пробовала, но так как это структуры ядра, сомневаюсь в том, что они работают быстрее. Есть ли еще варианты, как можно ускорить передачу данных от потока производителя к потребителям?

UPDATE:
Замеры производились на 6 ядрах, количество потоков-потребителей варьировалось от 5 до 20. Каждому потоку-потребителю передавались указатели на 4 строки не более 20 байт, которые он должен был скопировать и вывести. У каждого потока потребителя собственный неименованный канал, либо собственный мьютекс и переменная состояния. Замер времени осуществлялся от начала передачи данных потокам до вывода последней строки последним выполняющимся потоком. Первоначально результаты замеров варьировались в широких пределах, поэтому я добавила подсчет усредненного времени выполнения по 100 запускам каждого варианта.
Результаты:
переменная состояния + мьютекс:
5 потоков - 142 мсек, 10 потоков - 430 мсек, 20 потоков - 677 мсек
неименованный канал:
5 потоков - 168 мсек, 10 потоков - 483 мсек, 20 потоков - 870 мсек
разница становится заметнее при увеличении числа потоков-потребителей

У вопроса есть решение - Посмотреть?

https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc#comment298604_298516
@margosh, а что именно Вы измеряли в первом и втором случаях (и какие цифры получили)? Сколько потоков, ядер, размер передаваемых данных, характер их производства и обработки и т.п.

Ответы - Наиболее быстрый способ передачи данных потокам-потребителям / Наиболее быстрый способ передачи данных потокам-потребителям

Является ответом!
avp

20.02.2014 02:10:08

@margosh, в принципе, в некоторых случаях можно использовать "грязный" метод передачи данных, основанный на активном опросе флагов состояния (цикл без всякого ожидания) и почти не разделяемых ресурсах.

Например:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

struct trans {
  int *data;
  int busy, ready, cnt;
  double sum;
  long long nw;
};

struct trans trans[3];

void *
proc (void *a)
{
  long i = (long)a;

  printf ("thread %ld\n", i);

  trans[i].sum = 0;
  trans[i].cnt = 0;
  trans[i].nw = 0;
  do {
    trans[i].busy = 0;
    while (trans[i].busy == 0 && trans[i].ready == 0)
      trans[i].nw++;
    if (trans[i].busy) {
      int j;
      for (j = 0; j < 1024; j++)
        trans[i].sum += trans[i].data[j];
      free(trans[i].data);
      if (trans[i].cnt++ % 100000 == 0)
        printf ("thread %ld cnt: %d\n", i, trans[i].cnt);
    }
  } while (trans[i].ready == 0);

  printf ("end thread %ld\n", i);
}

int
main (int ac, char *av[])
{
  int i, j, k;
  pthread_t th[3];
  int  prodblk = 0;
  long long nw = 0;

  for (i = 0; i < 3; i++) {
    trans[i].busy = 1;
    trans[i].ready = 0;
    pthread_create(th+i, 0, proc, (void *)(long)i);
  }

  for (k = 0; k < 1000 * 1000; k++) {
    int *blk = malloc(sizeof(*blk) * 1024);
    for (j = 0; i < 1024; i++)
      blk[i] = rand();

    for (i = 0; trans[i].busy; i = (++i % 3))
      nw++;

    trans[i].data = blk;
    trans[i].busy = 1;
    prodblk++;
  }

  for (i = 0; i < 3; i++) 
    trans[i].ready = 1;
  for (i = 0; i < 3; i++) {
    if (pthread_join(th[i], 0))
      printf ("join %d err\n", i);
    printf ("%d sum: %f cnt: %d nw: %lld\n", 
            i, trans[i].sum, trans[i].cnt, trans[i].nw);
  }

  printf ("delta = %d prod nw = %lld\n", 
          prodblk - (trans[0].cnt + trans[1].cnt + trans[2].cnt), nw);

  return 0;
}

такая программа работает на 4-х ядрах и как показывает top, полностью сжирая все 400% CPU.

avp@avp-ubu1:~/hashcode$ gcc usynch.c -pthread
avp@avp-ubu1:~/hashcode$ ./a.out 
thread 1
thread 1 cnt: 1
thread 2
thread 0
thread 0 cnt: 1
thread 2 cnt: 1
thread 0 cnt: 100001
thread 0 cnt: 200001
thread 0 cnt: 300001
thread 0 cnt: 400001
thread 0 cnt: 500001
thread 0 cnt: 600001
thread 0 cnt: 700001
thread 0 cnt: 800001
thread 0 cnt: 900001
end thread 1
end thread 2
end thread 0
0 sum: 1089891918512436736.000000 cnt: 991231 nw: 664345180
1 sum: 8361100668315800.000000 cnt: 7614 nw: 1116687929
2 sum: 1268751999673707.000000 cnt: 1155 nw: 1171173905
delta = 0 prod nw = 7240419
avp@avp-ubu1:~/hashcode$

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

Но, может быть у Вас ситуация будет иной.

Однако, я не рекомендовал бы подобные методы для практического использования (кроме, может быть, "глубоко зашитых в железо").

https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298712_298634
@avp, а как же атомарность изменения флагов? (кстати, я пробовала сравнивать скорость инкрементирования счетчиков: под мьютексом, используя атомарные функции, и спинлок, почему-то быстрее получился вариант с мьютексом...) У Вас производитель не угоняется за потребителями вероятно из-за того, что он при каждой передаваймой порции данных вызывает malloc(). У меня же (не в тестовых примерах для сопоставления скоростей, а в реальной задаче) потоки-потребители выполняют большую работу, поэтому не успевают как раз они.
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298736_298634
@margosh, Вы все правилно говорите. Здесь просто продемонстрирован некий принцип и возможность (наверное сильно замаскированная -) (malloc/free)) в т.ч. косвенного взаимодействия между потоками. Понятно, что надо бы добавить volatile и сделать статические области для передачи данных. Понятно, что это подход строго для одного производителя, поэтому (мне кажется) атомарность изменения busy тут роли не играет. -- По поводу измерений -- Вы бы все же привели код и результаты замеров (можно в каком-нибудь pastebin). А иначе, опять получается какое-то пустое обсуждение принципов...
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298762_298634
@avp, ок, чуть-чуть позже выложу
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298804_298634
вот код и результаты : [cond.c][1] [cond_result][2] [pipe.c][3] [pipe_result][4] [1]: pastebin.com/fz65UxTz [2]: pastebin.com/XdqV7wUc [3]: pastebin.com/jJzPhCYZ [4]: pastebin.com/dvKAha9r
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298905_298634
@margosh, ОК. Сегодня-завтра обязательно посмотрю.
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment298957_298634
@margosh, я посмотрел. На мой взгляд Вы в основном меряете скорость запуска и завершения потоков, а не скорость передачи указателей из потока производителя нескольким потребителям. Попробуйте в таком варианте: create_threads(n); for(z = 0; z < RUN_COUNT; z ++){ pstr[0] = &str1[0]; ... for(i = 0; i < 4; i++){ for(j = 0; j < n; j++){ ptr = pstr[i]; write(fd[j*2 + 1], &ptr, sizeof(char *)); } } } join_threads(n); Я думаю, передача с мьютексом будет значительно быстрее. -- А зачем Вам нужен select() перед read() в tchcli()?
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment299006_298634
@avp, скорее, меряю общую скорость обработки данных от момента их передачи в потоки, до момента завершения их обработки (скорость запуска и завершения потока будет отличаться, т.к. началом отстчета считается запуск первого потока, а окончанием - время завершения обработки данных последним живым). я могла бы останавливать измерение до обработки данных, но после их считывания, но так обработка в обоих вариантах одинакова - вывод строки, я не считаю это критичным. select() - чтобы эксперимент был ближе к реальной системе,- в ней помимо этих данных, ожидаются сообщения еще с одного дескриптора
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298634#comment299110_298634
@margosh, просто запуск потока довольно дорогая операция, на ее фоне разница в передаче нескольких адресов по пайпу или через память с мьютексом не видна. Мне помнится, мы уже как-то обсуждали этот момент. Мое мнение -- если есть большое количество маленьких задач (время обработки по месту ее возникновения сравнимо с временем передачи этой задачи на другой процессор), не работающих с ожиданием событий, то никакими играми с потоками общее время обработки улучшить не получится. Обычно же -- прямо наоборот. Попытки распараллелить приводят только к ухудшению ситуации, причем во всех смыслах.
Nuklon

20.02.2014 06:05:57

Могу порекомендовать использовать очередь сообщений так как лучше не бывает и к тому же без очереди поток производитель не сможет отсылать новые данные потоку пока он не освободит мьютекс. Для этого создаёте свою синхронизированную(со спин блокировкой) FIFO-очередь(queue) на базе односвязного списка, очередь для каждого клиента. И кратко, если очередь пуста, потребитель пассивно ожидает...

p.s. хотя не рекомендуется использовать активное ожидание в многопроцессорной системе

https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299007_298864
@Nuklon, чень много вопросов к Вашему ответу : 1) под очередью вы понимаете собственноручно написанные списки, или IPC ? 2)"лучше не бывает" - это не аргумент, Вы проводили какой-то сравнительный анализ? 3)потребитель не может пассивно ожидать на спинлоке, Вы имели ввиду активное ожидание?
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299417_298864
@avp, время выполнения меряется после! запуска потоков, почему Вы решили иначе? Задачи выполняемые в реальной программе - отнюдь не маленькие, как я уже говорила, в моем случае потоки-потребители не успевают обрабатывать данные от производителя. Кстати, с наступающим праздником Вас и мужскую половину форума!
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299449_298864
@margosh, спасибо за поздравления! -- Вы правы, я ошибся. Посмотрел внимательней -- Вы действительно измеряете время передачи 4-ки сообщений всем потребителям. Может быть (для чистоты измерения именно времени передачи) стоит мерить время для каждого сообщения индивидуально (в struct timeval, "параллельных" tstr[j].glob_str[i])? Как-то я не уверен, что сейчас в (p->result) последних потоков не "подмешивается" время, которое затрачивается первыми уже на завершение... -- Прогнал у себя. Моя виртуалка раз в 5 медленнее. Причем, что интересно, pipe немного быстрее, чем cond.
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299714_298864
@avp, да, возможно вы правы, может и подмешивается время завершения нескольких, модифицирую и проверю еще раз. По поводу результатов - у меня они такие, как я привела -разница при небольшом количестве потоков действительно не слишком заметна, но при большом количестве потоков у меня быстрее вариант с переменной состояния. Однако, надо признать, что 20 потоков-потребителей в реальной системе у меня все равно пока не планируется, максимум 10, а потому результаты этих замеров мне и самой не слишком нравятся, хотелось бы найти какой-то наиболее быстрый способ передачи, чтобы разница была очевидна
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299760_298864
@margosh, под наиболее быстрым тут, видимо, надо понимать алгоритм, минимизирующий задержки производителя на всю синхронизацию? -- Предположим, что мы можем выделить произволителю все такты (или достаточно много) одного из CPU (hyperthread-а). Тогда первое, что приходит в голову, это попоробовать заменить в нем pthread_mutex_lock() на pthread_mutex_trylock() в цикле отсылки по потребителям, т.е. активно искать свободного потребителя. Возможно при этом стоит прикрепить (pthread_setaffinity_np()) производителя к конкретному CPU, а потребителям отдать другие.
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299764_298864
@avp, да, вероятно, хотя время на синхронизацию в потребителях меня тоже интересует. Если использовать активный поиск, то может имеет смысл вместо trylock использовать spinlock, как считаете? По поводу закрепления потока за конкретным ядром : Вы пробовали использовать это или назначение приоритета потокам? Есть ли какая то положительная динамика по времени? В литературе обычно советуют этим функционалом не баловаться и положиться на диспетчер.
https://ru.stackoverflow.com/questions/298516/%d0%9d%d0%b0%d0%b8%d0%b1%d0%be%d0%bb%d0%b5%d0%b5-%d0%b1%d1%8b%d1%81%d1%82%d1%80%d1%8b%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b0%d0%bc-%d0%bf%d0%be%d1%82%d1%80%d0%b5%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc/298864#comment299774_298864
@margosh, если честно, то со spin-ами и назначением приоритета я ничего не пробовал. С affinity игрался, но уже не помню для чего (точно не для замеров производительности). Из всех своих игр с потоками я и вынес для себя простое правило -- если вычислительной работы для потока меньше, чем на миллисекунду (т.е. пара миллионов "элементарных" инструкций) и в нем нет никакого ожидания по сокетам, клавиатуре и т.п., то поток не нужен (ни из пула, ни отдельно запускаемый). Мороки много, уверенности в отладке мало, а выигрыша по времени нет (обычно наоборот). А вообще, пробуйте (и опишите PLS).
Закрыть X