Как лучше всего продемонстрировать эффект настройки аффинности? - PullRequest
4 голосов
/ 19 июля 2010

Однажды я заметил, что Windows не поддерживает потоки, требующие большого объема вычислений, для конкретного ядра - вместо этого она продолжает переключать ядра.Поэтому я предположил, что работа будет выполняться быстрее, если поток сохранит доступ к тем же кэшам данных.И действительно, я смог наблюдать стабильное улучшение скорости ~ 1% после установки маски сродства потока для одного ядра (в потоке сжатия ppmd (de)).Но затем я попытался создать простую демонстрацию для этого эффекта, и более или менее не удалось - то есть, она работает, как и ожидалось, в моей системе (Q9450):

buflog=21 bufsize=2097152
(cache flush) first run    = 6.938s
time with default affinity = 6.782s
time with first core only  = 6.578s
speed gain is 3.01%

, но люди, которых я спросил, были не совсемспособен воспроизвести эффект.Любые предложения?

#include <stdio.h>
#include <windows.h>
int buflog=21, bufsize, bufmask;
char* a;
char* b;
volatile int r = 0;
__declspec(noinline)
int benchmark( char* a ) {
  int t0 = GetTickCount();
  int i,h=1,s=0;
  for( i=0; i<1000000000; i++ ) {
    h = h*200002979 + 1;
    s += ((int&)a[h&bufmask]) + ((int&)a[h&(bufmask>>2)]) + ((int&)a[h&(bufmask>>4)]);
  } r = s;
  t0 = GetTickCount() - t0;
  return t0;
}
DWORD WINAPI loadcore( LPVOID ) {
  SetThreadAffinityMask( GetCurrentThread(), 2 );
  while(1) benchmark(b);
}
int main( int argc, char** argv ) {
  if( (argc>1) && (atoi(argv[1])>16) ) buflog=atoi(argv[1]);
  bufsize=1<<buflog; bufmask=bufsize-1;
  a = new char[bufsize+4];
  b = new char[bufsize+4];
  printf( "buflog=%i bufsize=%i\n", buflog, bufsize );
  CreateThread( 0, 0, &loadcore, 0, 0, 0 );
  printf( "(cache flush) first run    = %.3fs\n", float(benchmark(a))/1000 );
  float t1 = benchmark(a); t1/=1000;
  printf( "time with default affinity = %.3fs\n", t1 );
  SetThreadAffinityMask( GetCurrentThread(), 1 );
  float t2 = benchmark(a); t2/=1000;
  printf( "time with first core only  = %.3fs\n", t2 );
  printf( "speed gain is %4.2f%%\n", (t1-t2)*100/t1 );
  return 0;
}

PS Я могу опубликовать ссылку на скомпилированную версию, если кому-то это нужно.

Ответы [ 4 ]

3 голосов
/ 02 августа 2010

сходство по умолчанию: сходство по умолчанию http://nishi.dreamhosters.com/u/paf_a0.png

привязка к ядру № 4 привязка к ядру # 4 http://nishi.dreamhosters.com/u/paf_a8.png

Теперь это архиватор. Вы действительно думаете, что рабочий поток собирается все вокруг процессора в порядке?

0 голосов
/ 02 августа 2010

Откуда вы знаете, что остальные 3 ядра используются вашим потоком, а не некоторыми системными потоками? Например, если вы пейджинг или что-то. Установите некоторые счетчики производительности для вашего процесса в perfmon и проверьте это предположение.

0 голосов
/ 01 августа 2010
  1. Windows не намеренно меняет процессы между процессорами. Если он сделал это с тобой, тебе просто не повезло.
  2. Вы можете получить небольшие перерывы в скорости, если вы получаете много попаданий в кеш, это зависит от вашего приложения. (Если у вас нет большого железа с забавной архитектурой памяти NUMA, это может вызвать все виды зависимостей).
  3. В вашем случае, почему бы просто не увеличить приоритет процесса, чтобы он никогда не был выгружен из процессора?
0 голосов
/ 19 июля 2010

Может быть, вам просто повезло, и на других компьютерах, на которых вы тестировали программу, кто-то сделал то же самое, что и вы, но его поток много спит.

Это приведет к вашей программепрерывается время от времени, когда другой поток назначается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...