JR>Чертовщина какая-то Ваш код показал у меня примерно 420000 и 270000. После этого попробовал вновь свой код, и он показал стабильно 1.94-1.97 вне зависимости от timeBeginPeriod, хотя буквально несколько дней назад этот-же тест показывал чёткую связь: 15 до timeBeginPeriod(1), и 1.95 — после. Перзагрузка ничего не меняет.
JR>Пока не знаю, в чём дело Попробую завтра разобраться.
Может в бэкграунде чота крутилось.. например тот же intellisense студии решил обновиться
![](/Forum/Images/smile.gif)
Кстати, запустил дома на q8400 w2k3 и получил очень любопытный результат — если юзать SignalForSingleObjectAndWait —
на 1м ядре (affinity 1) — 820000 sw/sec (приятно блин
![](/Forum/Images/biggrin.gif)
на 2х ядрах (affinity 3) — 290000
на 4х ядрах (affinity 15) — 40000
Если не юзать SignalForSingleObjectAndWait то цифры получаются: 610k, 310k, 40k соответственно.
Поражает и заставляет задуматься провал скорости переключения при работе на всех имеющихся ядрах. Интересно было бы увидеть цифры обладателей i7, вот слегка переделанный код (принимает affinity в командной строке):
// ctxswitchtest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "process.h"
#include "stdio.h"
#include "stdlib.h"
#define SIGNAL_AND_WAIT
struct trdpar
{
HANDLE wait;
HANDLE set;
volatile LONG *counter;
};
void __cdecl switch_perf_trd(void *p)
{
trdpar *par = (trdpar *)p;
#ifndef SIGNAL_AND_WAIT
for (;;)
{
::WaitForSingleObject(par->wait, INFINITE);
::SetEvent(par->set);
if (par->counter)InterlockedIncrement(par->counter);
}
#else
::WaitForSingleObject(par->wait, INFINITE);
for (;;)
{
::SignalObjectAndWait(par->set, par->wait, INFINITE, FALSE);
if (par->counter)InterlockedIncrement(par->counter);
}
#endif
}
void switch_perf()
{
volatile LONG counter = 0;
trdpar foo1 = {::CreateEvent(0, 0, 1, 0), ::CreateEvent(0, 0, 0, 0), 0};
trdpar foo2 = {foo1.set, foo1.wait, &counter};
_beginthread(switch_perf_trd, 0, &foo1);
_beginthread(switch_perf_trd, 0, &foo2);
for (InterlockedExchange(&counter, 0);;)
{
Sleep(1000);
printf("%u sw/sec \r", InterlockedExchange(&counter, 0));
}
}
int main(int argc, char **argv)
{
::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
if (argc>1)
::SetProcessAffinityMask(::GetCurrentProcess(), atoi(argv[1]));
switch_perf();
return 0;
}
Здравствуйте, ononim, Вы писали:
Разобрался.
Воспроизводиться у меня перестало из-за службы SqlExpress — до этого мерял без неё, а вчера она была запущена. Судя по всему, эта служба вызывает timeBeginPeriod(4), и мои вызовы уже не действовали. Остановил службу, стало воспроизводиться.
Ну а само такое поведение наблюдалось из-за совершенно идиотской ошибки в тесте
![](/Forum/Images/frown.gif)
Уже и асм перелопатил, а причина была под носом. Я ждал вызовом WaitForSingleObject(h, 1), а хендл (h) был вовсе не того эвента, который взводился в доп. потоке, вот и замерял не скорость переключения, а срабатывание по таймауту, осёл
После устранения бага привязка к кванту таймера пропала, так что всё, что я выше по этому поводу писал — чушь, наплевать и забыть.