function OSSchedulingAccuracyTest(configFile, duration) % OSSchedulingAccuracyTest([configFile][, duration=60]) % % Test accuracy of the operating systems scheduling for code execution of % code on the cpu, ie. Psychtoolbox and Matlab/Octave scripting language % code. % % 'configFile' Filename of benchmark configuration file. If none is specified, % the file fliptimingdefaultconfig.mat from the Psychtoolbox/PsychTests/TestConfigurations/ % folder is used for some reasonable default testing setup. % % 'duration' Duration of the test in seconds. Default is 60 seconds. % if nargin < 1 || isempty(configFile) configFile = [ PsychtoolboxRoot 'PsychTests' filesep 'TestConfigurations' filesep 'fliptimingdefaultconfig.mat' ]; end if ~exist(configFile, 'file') error('configFile ''%s'' does not exist or inaccessible!', configFile); end % Build filename for result file: Based on configname, machinename, date % and time: res.configFile = configFile; % Get basepath of config file: Will use it as basepath for result file: [basepath configBaseFile] = fileparts(configFile); basepath = [ PsychtoolboxRoot 'PsychTests' ]; res.OSName = OSName; comp = Screen('Computer'); res.computer = comp; if isfield(comp, 'system') res.OSSystem = comp.system; else res.OSSystem = 'Linux2.6'; end if isfield(comp, 'machineName') res.machineName = comp.machineName; else res.machineName = input('What is the machines name? ', 's'); end res.PrecisionWait = str2double(input('Precisionwait? [1/0]', 's')); res.Priority = str2double(input('Priority level? ', 's')); res.secondaryCPULoad = str2double(input('How much secondary CPU load? [%] ', 's')); res.secondaryGPULoad = str2double(input('How much secondary GPU load? [%] ', 's')); res.isMultiDisplay = input('Is this a multi-display setup? [y/n] ', 's'); res.withSound = input('With sound? [y/n] ', 's'); res.Comments = input('Any comments to add? ', 's'); res.mydate = datestr(clock); res.mydate(isspace(res.mydate)) = '_'; res.mydate(res.mydate == ':') = '-'; res.outFilename = sprintf('%s/TimingtestResults/Schedlat_%s_On_%s_at_%s.mat', basepath, configBaseFile, res.machineName, res.mydate); [foo, res.outFile] = fileparts(res.outFilename); fprintf('Will write results to file "%s" [path: %s]\n', res.outFile, res.outFilename); if nargin < 2 duration = []; end if isempty(duration) duration = 60; end res.duration = duration; Priority(res.Priority); secs = zeros(1, duration * 10000); t = secs; i = 0; fprintf('Running for %f seconds at Priority %f ...\n', duration, res.Priority); try % Preheat these: WaitSecs(0); GetSecs; % Stop after time tstopit: tstopit = GetSecs + duration; while 1 % Increment trial counter: i = i + 1; % Pick random wait duration between 0 and 10 msecs: secs(i) = rand * 0.010; % Try to wait that long, log real wait duration: if res.PrecisionWait > 0 tref = GetSecs; tnow = WaitSecs(secs(i)); else tref = GetSecs; tnow = WaitSecs('YieldSecs', secs(i)); end t(i) = tnow - tref; % Abort on timeout: if tnow > tstopit break; end end % Done. Switch to normal scheduling: Priority(0); catch Priority(0); psychrethrow(psychlasterror); end % Cut arrays down to real samplecount: t = t(1:i); secs = secs(1:i); % Log results: res.nSamples = i; res.realDelay = t; res.wantedDelay = secs; % Save results: save(res.outFilename, 'res', '-V6'); % Calculate scheduling jitter, ie., per-trial error, in msecs: jitter = 1000 * abs(t - secs); fprintf('After %i trials: Mean delay %f msecs, stddev = %f msecs, range = %f msecs.\n\n', i, mean(jitter), std(jitter), psychrange(jitter)); figure; hist(jitter, 100); title(sprintf('Scheduling latency histogram: Latency [msecs] vs. counts:\n(N=%i, Prio=%i)', i, res.Priority)); figure; plot(jitter); return;