public unsafe void Run() { Native32.AffinitizeThreadShardedNuma((uint)0, 2); RandomGenerator rng = new RandomGenerator(); LoadData(); input_ = new Input[8]; for (int i = 0; i < 8; i++) { input_[i].value = i; } #if DASHBOARD var dash = new Thread(() => DoContinuousMeasurements()); dash.Start(); #endif Thread[] workers = new Thread[threadCount]; Console.WriteLine("Executing setup."); // Setup the store for the YCSB benchmark. for (int idx = 0; idx < threadCount; ++idx) { int x = idx; workers[idx] = new Thread(() => SetupYcsb(x)); } Stopwatch sw = new Stopwatch(); sw.Start(); // Start threads. foreach (Thread worker in workers) { worker.Start(); } foreach (Thread worker in workers) { worker.Join(); } sw.Stop(); Console.WriteLine("Loading time: {0}ms", sw.ElapsedMilliseconds); long startTailAddress = store.Log.TailAddress; Console.WriteLine("Start tail address = " + startTailAddress); idx_ = 0; Console.WriteLine(store.DumpDistribution()); Console.WriteLine("Executing experiment."); // Run the experiment. for (int idx = 0; idx < threadCount; ++idx) { int x = idx; workers[idx] = new Thread(() => RunYcsb(x)); } // Start threads. foreach (Thread worker in workers) { worker.Start(); } Stopwatch swatch = new Stopwatch(); swatch.Start(); if (kCheckpointSeconds <= 0) { Thread.Sleep(TimeSpan.FromSeconds(kRunSeconds)); } else { int runSeconds = 0; while (runSeconds < kRunSeconds) { Thread.Sleep(TimeSpan.FromSeconds(kCheckpointSeconds)); store.TakeFullCheckpoint(out Guid token); runSeconds += kCheckpointSeconds; } } swatch.Stop(); done = true; foreach (Thread worker in workers) { worker.Join(); } #if DASHBOARD dash.Abort(); #endif double seconds = swatch.ElapsedMilliseconds / 1000.0; long endTailAddress = store.Log.TailAddress; Console.WriteLine("End tail address = " + endTailAddress); Console.WriteLine("Total " + total_ops_done + " ops done " + " in " + seconds + " secs."); Console.WriteLine("##, " + distribution + ", " + numaStyle + ", " + readPercent + ", " + threadCount + ", " + total_ops_done / seconds + ", " + (endTailAddress - startTailAddress)); }
private void RunYcsb(int thread_idx) { RandomGenerator rng = new ((uint)(1 + thread_idx)); if (numaStyle == 0) { Native32.AffinitizeThreadRoundRobin((uint)thread_idx); } else { Native32.AffinitizeThreadShardedNuma((uint)thread_idx, 2); // assuming two NUMA sockets } var sw = Stopwatch.StartNew(); Value value = default; long reads_done = 0; long writes_done = 0; #if DASHBOARD var tstart = Stopwatch.GetTimestamp(); var tstop1 = tstart; var lastWrittenValue = 0; int count = 0; #endif while (!done) { long chunk_idx = Interlocked.Add(ref idx_, YcsbConstants.kChunkSize) - YcsbConstants.kChunkSize; while (chunk_idx >= testLoader.TxnCount) { if (chunk_idx == testLoader.TxnCount) { idx_ = 0; } chunk_idx = Interlocked.Add(ref idx_, YcsbConstants.kChunkSize) - YcsbConstants.kChunkSize; } for (long idx = chunk_idx; idx < chunk_idx + YcsbConstants.kChunkSize && !done; ++idx) { Op op; int r = (int)rng.Generate(100); if (r < readPercent) { op = Op.Read; } else if (readPercent >= 0) { op = Op.Upsert; } else { op = Op.ReadModifyWrite; } switch (op) { case Op.Upsert: { store[txn_keys_[idx]] = value; ++writes_done; break; } case Op.Read: { if (store.TryGetValue(txn_keys_[idx], out value)) { ++reads_done; } break; } case Op.ReadModifyWrite: { store.AddOrUpdate(txn_keys_[idx], *(Value *)(input_ptr + (idx & 0x7)), (k, v) => new Value { value = v.value + (input_ptr + (idx & 0x7))->value }); ++writes_done; break; } default: throw new InvalidOperationException("Unexpected op: " + op); } } #if DASHBOARD count += (int)kChunkSize; //Check if stats collector is requesting for statistics if (writeStats[thread_idx]) { var tstart1 = tstop1; tstop1 = Stopwatch.GetTimestamp(); threadProgress[thread_idx] = count; threadThroughput[thread_idx] = (count - lastWrittenValue) / ((tstop1 - tstart1) / freq); lastWrittenValue = count; writeStats[thread_idx] = false; statsWritten[thread_idx].Set(); } #endif } sw.Stop(); Console.WriteLine("Thread " + thread_idx + " done; " + reads_done + " reads, " + writes_done + " writes, in " + sw.ElapsedMilliseconds + " ms."); Interlocked.Add(ref total_ops_done, reads_done + writes_done); }
void DoContinuousMeasurements() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (numaStyle == 0) { Native32.AffinitizeThreadRoundRobin((uint)threadCount + 1); } else { Native32.AffinitizeThreadShardedTwoNuma((uint)threadCount + 1); } } double totalThroughput, totalLatency, maximumLatency; double totalProgress; int ver = 0; using (var client = new WebClient()) { while (!allDone) { ver++; Thread.Sleep(measurementInterval); totalProgress = 0; totalThroughput = 0; totalLatency = 0; maximumLatency = 0; for (int i = 0; i < threadCount; i++) { writeStats[i] = true; } for (int i = 0; i < threadCount; i++) { statsWritten[i].WaitOne(); totalThroughput += threadThroughput[i]; totalProgress += threadProgress[i]; if (measureLatency) { totalLatency += threadAverageLatency[i]; if (threadMaximumLatency[i] > maximumLatency) { maximumLatency = threadMaximumLatency[i]; } } } if (measureLatency) { Console.WriteLine("{0} \t {1:0.000} \t {2} \t {3} \t {4} \t {5}", ver, totalThroughput / (double)1000000, totalLatency / threadCount, maximumLatency, store.Count, totalProgress); } else { Console.WriteLine("{0} \t {1:0.000} \t {2} \t {3}", ver, totalThroughput / (double)1000000, store.Count, totalProgress); } } } }
private void RunYcsb(int thread_idx) { RandomGenerator rng = new RandomGenerator((uint)(1 + thread_idx)); if (numaStyle == 0) { Native32.AffinitizeThreadRoundRobin((uint)thread_idx); } else { Native32.AffinitizeThreadShardedNuma((uint)thread_idx, 2); // assuming two NUMA sockets } waiter.Wait(); Stopwatch sw = new Stopwatch(); sw.Start(); Value value = default; Input input = default; Output output = default; long reads_done = 0; long writes_done = 0; #if DASHBOARD var tstart = Stopwatch.GetTimestamp(); var tstop1 = tstart; var lastWrittenValue = 0; int count = 0; #endif var session = store.For(functions).NewSession <Functions>(null, YcsbConstants.kAffinitizedSession); while (!done) { long chunk_idx = Interlocked.Add(ref idx_, YcsbConstants.kChunkSize) - YcsbConstants.kChunkSize; while (chunk_idx >= kTxnCount) { if (chunk_idx == kTxnCount) { idx_ = 0; } chunk_idx = Interlocked.Add(ref idx_, YcsbConstants.kChunkSize) - YcsbConstants.kChunkSize; } for (long idx = chunk_idx; idx < chunk_idx + YcsbConstants.kChunkSize && !done; ++idx) { Op op; int r = (int)rng.Generate(100); if (r < readPercent) { op = Op.Read; } else if (readPercent >= 0) { op = Op.Upsert; } else { op = Op.ReadModifyWrite; } if (idx % 512 == 0) { if (YcsbConstants.kAffinitizedSession) { session.Refresh(); } session.CompletePending(false); } switch (op) { case Op.Upsert: { session.Upsert(ref txn_keys_[idx], ref value, Empty.Default, 1); ++writes_done; break; } case Op.Read: { session.Read(ref txn_keys_[idx], ref input, ref output, Empty.Default, 1); ++reads_done; break; } case Op.ReadModifyWrite: { session.RMW(ref txn_keys_[idx], ref input_[idx & 0x7], Empty.Default, 1); ++writes_done; break; } default: throw new InvalidOperationException("Unexpected op: " + op); } } #if DASHBOARD count += (int)kChunkSize; //Check if stats collector is requesting for statistics if (writeStats[thread_idx]) { var tstart1 = tstop1; tstop1 = Stopwatch.GetTimestamp(); threadProgress[thread_idx] = count; threadThroughput[thread_idx] = (count - lastWrittenValue) / ((tstop1 - tstart1) / freq); lastWrittenValue = count; writeStats[thread_idx] = false; statsWritten[thread_idx].Set(); } #endif } session.CompletePending(true); session.Dispose(); sw.Stop(); #if DASHBOARD statsWritten[thread_idx].Set(); #endif Console.WriteLine("Thread " + thread_idx + " done; " + reads_done + " reads, " + writes_done + " writes, in " + sw.ElapsedMilliseconds + " ms."); Interlocked.Add(ref total_ops_done, reads_done + writes_done); }
internal FASTER_YcsbBenchmark(Key[] i_keys_, Key[] t_keys_, TestLoader testLoader) { // Affinize main thread to last core on first socket if not used by experiment var(numGrps, numProcs) = Native32.GetNumGroupsProcsPerGroup(); if ((testLoader.Options.NumaStyle == 0 && testLoader.Options.ThreadCount <= (numProcs - 1)) || (testLoader.Options.NumaStyle == 1 && testLoader.Options.ThreadCount <= numGrps * (numProcs - 1))) { Native32.AffinitizeThreadRoundRobin(numProcs - 1); } init_keys_ = i_keys_; txn_keys_ = t_keys_; numaStyle = testLoader.Options.NumaStyle; readPercent = testLoader.Options.ReadPercent; var lockImpl = testLoader.LockImpl; functions = new Functions(lockImpl != LockImpl.None); #if DASHBOARD statsWritten = new AutoResetEvent[threadCount]; for (int i = 0; i < threadCount; i++) { statsWritten[i] = new AutoResetEvent(false); } threadThroughput = new double[threadCount]; threadAverageLatency = new double[threadCount]; threadMaximumLatency = new double[threadCount]; threadProgress = new long[threadCount]; writeStats = new bool[threadCount]; freq = Stopwatch.Frequency; #endif input_ = new Input[8]; for (int i = 0; i < 8; i++) { input_[i].value = i; } device = Devices.CreateLogDevice(TestLoader.DevicePath, preallocateFile: true, deleteOnClose: true); if (YcsbConstants.kSmallMemoryLog) { store = new FasterKV <Key, Value> (YcsbConstants.kMaxKey / 2, new LogSettings { LogDevice = device, PreallocateLog = true, PageSizeBits = 22, SegmentSizeBits = 26, MemorySizeBits = 26 }, new CheckpointSettings { CheckPointType = CheckpointType.Snapshot, CheckpointDir = testLoader.BackupPath }); } else { store = new FasterKV <Key, Value> (YcsbConstants.kMaxKey / 2, new LogSettings { LogDevice = device, PreallocateLog = true }, new CheckpointSettings { CheckPointType = CheckpointType.Snapshot, CheckpointDir = testLoader.BackupPath }); } }
private void RunYcsb(int thread_idx) { RandomGenerator rng = new RandomGenerator((uint)(1 + thread_idx)); if (numaStyle == 0) { Native32.AffinitizeThreadRoundRobin((uint)thread_idx); } else { Native32.AffinitizeThreadShardedNuma((uint)thread_idx, 2); // assuming two NUMA sockets } Stopwatch sw = new Stopwatch(); sw.Start(); Value value = default(Value); long reads_done = 0; long writes_done = 0; #if DASHBOARD var tstart = Stopwatch.GetTimestamp(); var tstop1 = tstart; var lastWrittenValue = 0; int count = 0; #endif store.StartSession(); while (!done) { long chunk_idx = Interlocked.Add(ref idx_, kChunkSize) - kChunkSize; while (chunk_idx >= kTxnCount) { if (chunk_idx == kTxnCount) { idx_ = 0; } chunk_idx = Interlocked.Add(ref idx_, kChunkSize) - kChunkSize; } var local_txn_keys_ptr = txn_keys_ptr + chunk_idx; for (long idx = chunk_idx; idx < chunk_idx + kChunkSize && !done; ++idx, ++local_txn_keys_ptr) { Op op; int r = (int)rng.Generate(100); if (r < readPercent) { op = Op.Read; } else if (readPercent >= 0) { op = Op.Upsert; } else { op = Op.ReadModifyWrite; } if (idx % 256 == 0) { store.Refresh(); if (idx % 65536 == 0) { store.CompletePending(false); } } switch (op) { case Op.Upsert: { store.Upsert(local_txn_keys_ptr, &value, null, 1); ++writes_done; break; } case Op.Read: { Status result = store.Read(local_txn_keys_ptr, null, (Output *)&value, null, 1); if (result == Status.OK) { ++reads_done; } break; } case Op.ReadModifyWrite: { Status result = store.RMW(local_txn_keys_ptr, input_ptr + (idx & 0x7), null, 1); if (result == Status.OK) { ++writes_done; } break; } default: throw new InvalidOperationException("Unexpected op: " + op); } } #if DASHBOARD count += (int)kChunkSize; //Check if stats collector is requesting for statistics if (writeStats[thread_idx]) { var tstart1 = tstop1; tstop1 = Stopwatch.GetTimestamp(); threadProgress[thread_idx] = count; threadThroughput[thread_idx] = (count - lastWrittenValue) / ((tstop1 - tstart1) / freq); lastWrittenValue = count; writeStats[thread_idx] = false; statsWritten[thread_idx].Set(); } #endif } store.CompletePending(true); store.StopSession(); sw.Stop(); Console.WriteLine("Thread " + thread_idx + " done; " + reads_done + " reads, " + writes_done + " writes, in " + sw.ElapsedMilliseconds + " ms."); Interlocked.Add(ref total_ops_done, reads_done + writes_done); }