private async Task LogPerformanceWorkloadWorker( ILogicalLog lLog, byte[] recordBuffer, TestLogNotification tn75, CancellationToken tn75CancelToken, CancellationToken CancelToken ) { try { Task taskUsageNotification75; long bytes = 0; taskUsageNotification75 = tn75.SetupLogUsageNotificationAsync(lLog, 75, tn75CancelToken); if (_DedicatedLogOnly) { await lLog.ConfigureWritesToOnlyDedicatedLogAsync(CancellationToken.None); } bool canceled = false; this.StartPerfWorkloads.WaitOne(); while (!canceled) { await lLog.AppendAsync(recordBuffer, 0, 40, /*recordBuffer.Length,*/ CancellationToken.None); bytes += 40; /*recordBuffer.Length;*/ if (tn75.Fired) { // // Truncate back to 10% // long allowedData = lLog.Length / 10; long truncationPosition = bytes - allowedData; lLog.TruncateHead(truncationPosition); taskUsageNotification75 = tn75.SetupLogUsageNotificationAsync(lLog, 75, tn75CancelToken); } if (CancelToken.IsCancellationRequested) { canceled = true; } } await lLog.FlushWithMarkerAsync(CancellationToken.None); Interlocked.Add(ref this.TotalByteCount, bytes); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.WriteLine("Tasks completed"); return; }
public void LogPerformanceWorkloadTest( out float MBPerSecond ) { try { //* Local functions Func <ILogManager> MakeManager = (() => { Task <ILogManager> t = LogManager.OpenAsync(LogManager.LoggerType.Default, CancellationToken.None); t.Wait(); return(t.Result); }); Func <ILogManager, string, Guid, long, uint, uint, IPhysicalLog> MakePhyLog = (( ILogManager manager, string pathToCommonContainer, Guid physicalLogId, long containerSize, uint maximumNumberStreams, uint maximumLogicalLogBlockSize) => { Task <IPhysicalLog> t = manager.CreatePhysicalLogAsync( pathToCommonContainer, physicalLogId, containerSize, maximumNumberStreams, maximumLogicalLogBlockSize, 0, // Physical logs are not sparse CancellationToken.None); t.Wait(); return(t.Result); }); Func <ILogManager, string, Guid, IPhysicalLog> OpenPhyLog = (( ILogManager manager, string pathToCommonContainer, Guid physicalLogId) => { Task <IPhysicalLog> t = manager.OpenPhysicalLogAsync( pathToCommonContainer, physicalLogId, false, CancellationToken.None); t.Wait(); return(t.Result); }); string physLogName = PlatformPathPrefix + _SharedDrive + PathSeparator + "PerfWorkloadTestP.log"; Console.WriteLine("Physical Log: {0}", physLogName); ILogManager logManager = MakeManager(); try { File.Delete(physLogName.Substring(4)); } catch (Exception) { // ok if this fails } Console.WriteLine("Raw Record size is {0}", _RecordSize); Guid logId = Guid.NewGuid(); string logName = physLogName; IPhysicalLog phyLog = MakePhyLog( logManager, logName, logId, _LogSize, 0, 4 * _RecordSize); // // Determine the largest record size. We write full records to maximmize our I/O rate. // Max record size is determined by the Maximum block size plus the metadata space (4K) minus the // overhead of the headers. // //const int MaxLogBlkSize = 1024 * 1024; //const int recordSize = 131; CancellationTokenSource[] cancelToken = new CancellationTokenSource[_NumberTasks]; Task[] tasks = new Task[_NumberTasks]; ILogicalLog[] lLogs = new ILogicalLog[_NumberTasks]; TestLogNotification[] tn75 = new TestLogNotification[_NumberTasks]; CancellationTokenSource[] cancelTokenSource75 = new CancellationTokenSource[_NumberTasks]; int bytesToWrite = 1; this.StartPerfWorkloads.Reset(); for (int i = 0; i < _NumberTasks; i++) { // // MUltiply record size by 4 so log is created with correct geometry // Guid lLogId = Guid.NewGuid(); string logicalLogName = PlatformPathPrefix + _DedicatedDrive + PathSeparator + "Perf" + lLogId.ToString() + ".log"; lLogs[i] = CreateLogicalLog(phyLog, lLogId, null, logicalLogName, null, _LlogSize, 4 * _RecordSize); lLogs[i].CloseAsync(CancellationToken.None).Wait(); lLogs[i] = null; lLogs[i] = OpenLogicalLog(phyLog, lLogId); // // Harvest the size of a complete buffer to write // bytesToWrite = (int)lLogs[i].MaximumBlockSize; // // Truncate at 75% // cancelToken[i] = new CancellationTokenSource(); CancellationToken token = cancelToken[i].Token; tn75[i] = new TestLogNotification(); cancelTokenSource75[i] = new CancellationTokenSource(); } // // Get a buffer // Console.WriteLine("Each formatted record contains {0} bytes", bytesToWrite); byte[] result = new byte[(uint)bytesToWrite]; for (int ix = 0; ix < result.Length; ix++) { result[ix] = (byte)(ix % 131); } StartWorkloadThreads(lLogs, result, tn75, cancelTokenSource75, cancelToken, out MBPerSecond); for (int i = 0; i < _NumberTasks; i++) { lLogs[i].CloseAsync(CancellationToken.None).Wait(); lLogs[i] = null; } phyLog.CloseAsync(CancellationToken.None).Wait(); phyLog = null; //* Cleanup logManager.DeletePhysicalLogAsync(logName, logId, CancellationToken.None).Wait(); logManager.CloseAsync(CancellationToken.None).Wait(); try { File.Delete(physLogName.Substring(4)); } catch (Exception) { // ok if this fails } } catch (Exception ex) { Console.WriteLine(ex.ToString()); throw; } }
private void StartWorkloadThreads( ILogicalLog[] lLog, byte[] recordBuffer, TestLogNotification[] tn75, CancellationTokenSource[] tn75CancelToken, CancellationTokenSource[] CancelToken, out float MBPerSecond ) { int numberTasks = tn75.Length; Task[] tasks = new Task[numberTasks]; TotalByteCount = 0; for (int i = 0; i < numberTasks; i++) { int ii = i; tasks[i] = Task.Factory.StartNew(() => { ILogicalLog logicalLog = lLog[ii]; TestLogNotification tn75a = tn75[ii]; CancellationToken tn75ct = tn75CancelToken[ii].Token; CancellationToken ct = CancelToken[ii].Token; LogPerformanceWorkloadWorker(logicalLog, recordBuffer, tn75a, tn75ct, ct).Wait(); }); } long StartTicks = DateTime.Now.Ticks; this.StartPerfWorkloads.Set(); Thread.CurrentThread.Join(TimeSpan.FromSeconds(_TimeToRunInSeconds)); for (int i = 0; i < numberTasks; i++) { try { tn75CancelToken[i].Cancel(); } catch { } CancelToken[i].Cancel(); } Task.WaitAll(tasks); long byteCount = TotalByteCount; long EndTicks = DateTime.Now.Ticks; long totalTimeInSeconds = (EndTicks - StartTicks) / 10000000; long bytesPerSecond = TotalByteCount / totalTimeInSeconds; float mbPerSecond = (bytesPerSecond / (1024 * 1024)); Console.WriteLine("Number Tasks: {0}", numberTasks); Console.WriteLine("Seconds running {0}", totalTimeInSeconds); Console.WriteLine("RecordSize {0}", recordBuffer.Length); Console.WriteLine("Total bytes {0}", TotalByteCount); Console.WriteLine("Bytes per second: {0}\nMB per second: {1}", bytesPerSecond, mbPerSecond); MBPerSecond = mbPerSecond; }