Skip to content

Commit d9b3af5

Browse files
committed
Added multi-numa optimization.
1 parent 11d7f89 commit d9b3af5

File tree

8 files changed

+90
-42
lines changed

8 files changed

+90
-42
lines changed

OKEGui/OKEGui/Job/VideoJob/VideoJob.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class VideoJob : Job
1717
public double Fps;
1818
public uint FpsNum;
1919
public uint FpsDen;
20+
public int NumaNode;
2021

2122
public VideoJob() : base()
2223
{

OKEGui/OKEGui/JobProcessor/CommandlineJobProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public void start()
129129
//proc.EnableRaisingEvents = true;
130130
//proc.Exited += new EventHandler(proc_Exited);
131131
bWaitForExit = false;
132-
Debugger.Log(0, "Job command line", pstart.FileName + " " + pstart.Arguments);
132+
Debugger.Log(0, "Job command line", pstart.FileName + " " + pstart.Arguments + "\n");
133133

134134
try {
135135
bool started = proc.Start();

OKEGui/OKEGui/JobProcessor/Video/x265Encoder.cs

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,31 @@
99

1010
namespace OKEGui
1111
{
12-
public class x265Encoder : CommandlineVideoEncoder
12+
public class X265Encoder : CommandlineVideoEncoder
1313
{
14-
// public static readonly JobProcessorFactory Factory = new JobProcessorFactory(new ProcessorFactory(init), "x265Encoder");
14+
private readonly string x265Path = "";
15+
private readonly string vspipePath = "";
1516

16-
private string x265Path = "";
17-
private string vspipePath = "";
18-
19-
public static IJobProcessor init(Job j, string extractParam)
20-
{
21-
if (j is VideoJob && ((j as VideoJob).CodecString == "X265" || (j as VideoJob).CodecString == "HEVC")) {
22-
return new x265Encoder((j as VideoJob), extractParam);
23-
}
24-
return null;
25-
}
26-
27-
public x265Encoder(Job j, string extractParam)
28-
: base()
17+
public X265Encoder(Job j) : base()
2918
{
3019
job = j as VideoJob;
3120
getInputProperties(job);
3221

3322
executable = Path.Combine(Environment.SystemDirectory, "cmd.exe");
3423

35-
if (File.Exists(job.EncoderPath)) {
24+
if (File.Exists(job.EncoderPath))
25+
{
3626
this.x265Path = job.EncoderPath;
3727
}
3828

3929
// 获取VSPipe路径
4030
this.vspipePath = ConfigManager.Config.vspipePath;
4131

42-
commandLine = BuildCommandline(extractParam);
32+
commandLine = BuildCommandline(job.EncodeParam, job.NumaNode);
4333
}
4434

4535
public override void ProcessLine(string line, StreamType stream)
4636
{
47-
//if (line.StartsWith("[")) // status update
48-
//{
49-
// int frameNumberStart = line.IndexOf("]", 4) + 2;
50-
// int frameNumberEnd = line.IndexOf("/");
51-
// if (frameNumberStart > 0 && frameNumberEnd > 0 && frameNumberEnd > frameNumberStart)
52-
// if (base.setFrameNumber(line.Substring(frameNumberStart, frameNumberEnd - frameNumberStart).Trim()))
53-
// return;
54-
//}
5537
if (line.Contains("x265 [error]:"))
5638
{
5739
OKETaskException ex = new OKETaskException(Constants.x265ErrorSmr);
@@ -66,15 +48,17 @@ public override void ProcessLine(string line, StreamType stream)
6648
throw ex;
6749
}
6850

69-
if (line.ToLowerInvariant().Contains("encoded")) {
51+
if (line.ToLowerInvariant().Contains("encoded"))
52+
{
7053
Regex rf = new Regex("encoded ([0-9]+) frames in ([0-9]+.[0-9]+)s \\(([0-9]+.[0-9]+) fps\\), ([0-9]+.[0-9]+) kb/s, Avg QP:(([0-9]+.[0-9]+))");
7154

7255
var result = rf.Split(line);
7356

7457
ulong reportedFrames = ulong.Parse(result[1]);
7558

7659
// 这里是平均速度
77-
if (!base.setSpeed(result[3])) {
60+
if (!base.setSpeed(result[3]))
61+
{
7862
return;
7963
}
8064

@@ -86,32 +70,34 @@ public override void ProcessLine(string line, StreamType stream)
8670
Regex r = new Regex("([0-9]+) frames: ([0-9]+.[0-9]+) fps, ([0-9]+.[0-9]+) kb/s", RegexOptions.IgnoreCase);
8771

8872
var status = r.Split(line);
89-
if (status.Length < 3) {
73+
if (status.Length < 3)
74+
{
9075
return;
9176
}
9277

93-
if (!base.setFrameNumber(status[1], true)) {
78+
if (!base.setFrameNumber(status[1], true))
79+
{
9480
return;
9581
}
9682

9783
base.setBitrate(status[3], "kb/s");
9884

99-
if (!base.setSpeed(status[2])) {
85+
if (!base.setSpeed(status[2]))
86+
{
10087
return;
10188
}
10289

10390
base.ProcessLine(line, stream);
10491
}
10592

106-
// TODO: 改为静态
107-
public /*static*/ string BuildCommandline(string extractParam)
93+
private string BuildCommandline(string extractParam, int numaNode)
10894
{
10995
StringBuilder sb = new StringBuilder();
11096

111-
sb.Append("/c ");
112-
sb.Append("\"");
97+
sb.Append("/c \"start \"foo\" /b /wait /affinity 0xFFFFFFF /node ");
98+
sb.Append(numaNode.ToString());
11399
// 构建vspipe参数
114-
sb.Append("\"" + vspipePath + "\"");
100+
sb.Append(" \"" + vspipePath + "\"");
115101
sb.Append(" --y4m ");
116102
sb.Append("\"" + job.Input + "\"");
117103
sb.Append(" - | ");

OKEGui/OKEGui/MainWindow.xaml.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Windows.Controls;
66
using System.Windows.Input;
77
using OKEGui.Utils;
8+
using OKEGui.Worker;
89

910
namespace OKEGui
1011
{
@@ -41,8 +42,12 @@ public MainWindow()
4142
BtnStop.IsEnabled = false;
4243
BtnEdit.IsEnabled = false;
4344

44-
WorkerCount++;
45-
wm.AddWorker("工作单元-" + WorkerCount.ToString());
45+
int numaCount = NumaNode.NumaCount;
46+
for (int i = 0; i < numaCount; i++)
47+
{
48+
WorkerCount++;
49+
wm.AddWorker("工作单元-" + WorkerCount.ToString());
50+
}
4651
this.WorkerNumber.Text = "工作单元:" + WorkerCount.ToString();
4752
}
4853

OKEGui/OKEGui/OKEGui.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
<Compile Include="Utils\SafeProxy.cs" />
136136
<Compile Include="Utils\VapourSynthHelper.cs" />
137137
<Compile Include="Utils\WindowsUtil.cs" />
138+
<Compile Include="Worker\NumaNode.cs" />
138139
<Compile Include="Worker\WorkerManager.cs" />
139140
</ItemGroup>
140141
<ItemGroup>

OKEGui/OKEGui/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@
4747
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
4848
// 方法是按如下所示使用“*”: :
4949
// [assembly: AssemblyVersion("1.0.*")]
50-
[assembly: AssemblyVersion("4.0.*")]
50+
[assembly: AssemblyVersion("4.1.*")]

OKEGui/OKEGui/Worker/NumaNode.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace OKEGui.Worker
9+
{
10+
static class NumaNode
11+
{
12+
[DllImport("Kernel32.dll")]
13+
[return: MarshalAsAttribute(UnmanagedType.Bool)]
14+
public static extern bool GetNumaHighestNodeNumber([Out] out uint HighestNodeNumber);
15+
16+
public static readonly int NumaCount;
17+
static int CurrentNuma;
18+
19+
static NumaNode()
20+
{
21+
GetNumaHighestNodeNumber(out uint temp);
22+
CurrentNuma = (int)temp;
23+
NumaCount = CurrentNuma + 1;
24+
}
25+
26+
public static int NextNuma()
27+
{
28+
int res = CurrentNuma;
29+
CurrentNuma = (CurrentNuma - 1 + NumaCount) % NumaCount;
30+
return res;
31+
}
32+
33+
public static int PrevNuma()
34+
{
35+
int res = CurrentNuma;
36+
CurrentNuma = (CurrentNuma + 1) % NumaCount;
37+
return res;
38+
}
39+
40+
public static string X265PoolsParam(int currentNuma)
41+
{
42+
string[] res = Enumerable.Repeat("-", NumaCount).ToArray();
43+
res[currentNuma] = "+";
44+
return string.Join(",", res);
45+
}
46+
}
47+
}

OKEGui/OKEGui/Worker/WorkerManager.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using OKEGui.Utils;
77
using OKEGui.JobProcessor;
88

9-
namespace OKEGui
9+
namespace OKEGui.Worker
1010
{
1111
// TODO: 目前只考虑压制全部任务;以后可能会各步骤分开进行,或者进行其他任务
1212
// TODO: TaskManger 做成接口。各种不同类型任务分开管理。
@@ -22,6 +22,7 @@ internal struct WorkerArgs
2222
public WorkerType RunningType;
2323
public TaskManager taskManager;
2424
public BackgroundWorker bgWorker;
25+
public int numaNode;
2526
}
2627

2728
public class WorkerManager
@@ -104,6 +105,7 @@ public bool StartWorker(string name)
104105
args.RunningType = workerType[name];
105106
args.taskManager = tm;
106107
args.bgWorker = worker;
108+
args.numaNode = NumaNode.NextNuma();
107109

108110
worker.RunWorkerAsync(args);
109111
return true;
@@ -310,6 +312,12 @@ private void WorkerDoWork(object sender, DoWorkEventArgs e)
310312
videoJob.FpsNum = task.FpsNum;
311313
videoJob.FpsDen = task.FpsDen;
312314

315+
videoJob.NumaNode = args.numaNode;
316+
if (!task.EncoderParam.ToLower().Contains("--pools"))
317+
{
318+
videoJob.EncodeParam += " --pools " + NumaNode.X265PoolsParam(videoJob.NumaNode);
319+
}
320+
313321
task.JobQueue.Enqueue(videoJob);
314322
}
315323

@@ -333,7 +341,7 @@ private void WorkerDoWork(object sender, DoWorkEventArgs e)
333341
if (job is AudioJob)
334342
{
335343
AudioJob audioJob = job as AudioJob;
336-
string srcFmt = Path.GetExtension(audioJob.Input).ToUpper().Remove(0,1);
344+
string srcFmt = Path.GetExtension(audioJob.Input).ToUpper().Remove(0, 1);
337345
if (srcFmt == "FLAC" && audioJob.CodecString == "AAC")
338346
{
339347
task.CurrentStatus = "音频转码中";
@@ -380,7 +388,7 @@ private void WorkerDoWork(object sender, DoWorkEventArgs e)
380388
{
381389
task.CurrentStatus = "获取信息中";
382390
task.IsUnKnowProgress = true;
383-
IJobProcessor processor = x265Encoder.init(job, task.EncoderParam);
391+
X265Encoder processor = new X265Encoder(job);
384392

385393
task.CurrentStatus = "压制中";
386394
task.ProgressValue = 0.0;

0 commit comments

Comments
 (0)