front-cpu 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +475 -0
  2. package/README.zh-CN.md +474 -0
  3. package/dist/Pipeline.d.ts +119 -0
  4. package/dist/Pipeline.d.ts.map +1 -0
  5. package/dist/Pipeline.js +373 -0
  6. package/dist/Pipeline.js.map +1 -0
  7. package/dist/debug.d.ts +3 -0
  8. package/dist/debug.d.ts.map +1 -0
  9. package/dist/debug.js +12 -0
  10. package/dist/debug.js.map +1 -0
  11. package/dist/index.d.ts +20 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +19 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/interfaces.d.ts +49 -0
  16. package/dist/interfaces.d.ts.map +1 -0
  17. package/dist/interfaces.js +8 -0
  18. package/dist/interfaces.js.map +1 -0
  19. package/dist/isa/index.d.ts +20 -0
  20. package/dist/isa/index.d.ts.map +1 -0
  21. package/dist/isa/index.js +26 -0
  22. package/dist/isa/index.js.map +1 -0
  23. package/dist/isa/types.d.ts +144 -0
  24. package/dist/isa/types.d.ts.map +1 -0
  25. package/dist/isa/types.js +10 -0
  26. package/dist/isa/types.js.map +1 -0
  27. package/dist/logging/CPUConsole.d.ts +105 -0
  28. package/dist/logging/CPUConsole.d.ts.map +1 -0
  29. package/dist/logging/CPUConsole.js +471 -0
  30. package/dist/logging/CPUConsole.js.map +1 -0
  31. package/dist/logging/CPUDebugger.d.ts +91 -0
  32. package/dist/logging/CPUDebugger.d.ts.map +1 -0
  33. package/dist/logging/CPUDebugger.js +166 -0
  34. package/dist/logging/CPUDebugger.js.map +1 -0
  35. package/dist/logging/CPUEventCollector.d.ts +90 -0
  36. package/dist/logging/CPUEventCollector.d.ts.map +1 -0
  37. package/dist/logging/CPUEventCollector.js +353 -0
  38. package/dist/logging/CPUEventCollector.js.map +1 -0
  39. package/dist/logging/CPULogger.d.ts +150 -0
  40. package/dist/logging/CPULogger.d.ts.map +1 -0
  41. package/dist/logging/CPULogger.js +336 -0
  42. package/dist/logging/CPULogger.js.map +1 -0
  43. package/dist/logging/index.d.ts +10 -0
  44. package/dist/logging/index.d.ts.map +1 -0
  45. package/dist/logging/index.js +16 -0
  46. package/dist/logging/index.js.map +1 -0
  47. package/dist/logging/runtime.d.ts +37 -0
  48. package/dist/logging/runtime.d.ts.map +1 -0
  49. package/dist/logging/runtime.js +42 -0
  50. package/dist/logging/runtime.js.map +1 -0
  51. package/dist/logging/stack-parser.d.ts +22 -0
  52. package/dist/logging/stack-parser.d.ts.map +1 -0
  53. package/dist/logging/stack-parser.js +144 -0
  54. package/dist/logging/stack-parser.js.map +1 -0
  55. package/dist/logging/types.d.ts +73 -0
  56. package/dist/logging/types.d.ts.map +1 -0
  57. package/dist/logging/types.js +47 -0
  58. package/dist/logging/types.js.map +1 -0
  59. package/dist/scheduling/ResourceStrategyRegistry.d.ts +61 -0
  60. package/dist/scheduling/ResourceStrategyRegistry.d.ts.map +1 -0
  61. package/dist/scheduling/ResourceStrategyRegistry.js +109 -0
  62. package/dist/scheduling/ResourceStrategyRegistry.js.map +1 -0
  63. package/dist/scheduling/index.d.ts +6 -0
  64. package/dist/scheduling/index.d.ts.map +1 -0
  65. package/dist/scheduling/index.js +5 -0
  66. package/dist/scheduling/index.js.map +1 -0
  67. package/dist/scheduling/types.d.ts +44 -0
  68. package/dist/scheduling/types.d.ts.map +1 -0
  69. package/dist/scheduling/types.js +5 -0
  70. package/dist/scheduling/types.js.map +1 -0
  71. package/dist/stages/EX.d.ts +17 -0
  72. package/dist/stages/EX.d.ts.map +1 -0
  73. package/dist/stages/EX.js +95 -0
  74. package/dist/stages/EX.js.map +1 -0
  75. package/dist/stages/IF.d.ts +41 -0
  76. package/dist/stages/IF.d.ts.map +1 -0
  77. package/dist/stages/IF.js +83 -0
  78. package/dist/stages/IF.js.map +1 -0
  79. package/dist/stages/RES.d.ts +17 -0
  80. package/dist/stages/RES.d.ts.map +1 -0
  81. package/dist/stages/RES.js +37 -0
  82. package/dist/stages/RES.js.map +1 -0
  83. package/dist/stages/SCH.d.ts +77 -0
  84. package/dist/stages/SCH.d.ts.map +1 -0
  85. package/dist/stages/SCH.js +270 -0
  86. package/dist/stages/SCH.js.map +1 -0
  87. package/dist/stages/WB.d.ts +19 -0
  88. package/dist/stages/WB.d.ts.map +1 -0
  89. package/dist/stages/WB.js +102 -0
  90. package/dist/stages/WB.js.map +1 -0
  91. package/dist/types.d.ts +111 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +26 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/utils/InstructionCancellation.d.ts +31 -0
  96. package/dist/utils/InstructionCancellation.d.ts.map +1 -0
  97. package/dist/utils/InstructionCancellation.js +53 -0
  98. package/dist/utils/InstructionCancellation.js.map +1 -0
  99. package/dist/utils/abortable.d.ts +30 -0
  100. package/dist/utils/abortable.d.ts.map +1 -0
  101. package/dist/utils/abortable.js +76 -0
  102. package/dist/utils/abortable.js.map +1 -0
  103. package/dist/utils/request.d.ts +27 -0
  104. package/dist/utils/request.d.ts.map +1 -0
  105. package/dist/utils/request.js +96 -0
  106. package/dist/utils/request.js.map +1 -0
  107. package/package.json +74 -0
  108. package/src/Pipeline.ts +475 -0
  109. package/src/debug.ts +15 -0
  110. package/src/index.ts +67 -0
  111. package/src/interfaces.ts +53 -0
  112. package/src/isa/index.ts +34 -0
  113. package/src/isa/types.ts +178 -0
  114. package/src/logging/CPUConsole.md +843 -0
  115. package/src/logging/CPUConsole.ts +631 -0
  116. package/src/logging/CPUDebugger.ts +235 -0
  117. package/src/logging/CPUEventCollector.ts +418 -0
  118. package/src/logging/CPULogger.ts +435 -0
  119. package/src/logging/CPU_LOGGING_DESIGN.md +1319 -0
  120. package/src/logging/USAGE_GUIDE.md +505 -0
  121. package/src/logging/index.ts +21 -0
  122. package/src/logging/runtime.ts +96 -0
  123. package/src/logging/stack-parser.ts +168 -0
  124. package/src/logging/types.ts +101 -0
  125. package/src/scheduling/ResourceStrategyRegistry.ts +124 -0
  126. package/src/scheduling/index.ts +13 -0
  127. package/src/scheduling/types.ts +47 -0
  128. package/src/stages/EX.ts +121 -0
  129. package/src/stages/IF.ts +103 -0
  130. package/src/stages/RES.ts +46 -0
  131. package/src/stages/SCH.ts +331 -0
  132. package/src/stages/WB.ts +127 -0
  133. package/src/types.ts +118 -0
  134. package/src/utils/InstructionCancellation.ts +73 -0
  135. package/src/utils/abortable.ts +89 -0
  136. package/src/utils/request.ts +125 -0
@@ -0,0 +1,435 @@
1
+ /**
2
+ * CPU 日志记录器
3
+ *
4
+ * 职责:
5
+ * 1. 存储和索引所有 CPU 事件
6
+ * 2. 提供强大的查询 API
7
+ * 3. 自动分析和聚合
8
+ */
9
+
10
+ import type { PipelineStage, InstructionStatus } from '../types'
11
+ import { CPUEventType, type CPUEvent } from './types'
12
+
13
+ export class CPULogger {
14
+ // 存储
15
+ private events: CPUEvent[] = []
16
+ private maxEvents: number = 10000 // 保留最近 10000 条事件
17
+
18
+ // 索引
19
+ private eventsByInstruction = new Map<string, CPUEvent[]>()
20
+ private eventsByCorrelation = new Map<string, CPUEvent[]>()
21
+ private eventsByType = new Map<CPUEventType, CPUEvent[]>()
22
+
23
+ // 统计
24
+ private stats = {
25
+ totalEvents: 0,
26
+ eventCounts: new Map<CPUEventType, number>(),
27
+ instructionCounts: new Map<string, number>(),
28
+ }
29
+
30
+ /**
31
+ * 批量接收事件
32
+ */
33
+ ingestBatch(events: CPUEvent[]): void {
34
+ for (const event of events) {
35
+ this.ingestEvent(event)
36
+ }
37
+ }
38
+
39
+ /**
40
+ * 接收单个事件
41
+ */
42
+ private ingestEvent(event: CPUEvent): void {
43
+ // 存储
44
+ this.events.push(event)
45
+ if (this.events.length > this.maxEvents) {
46
+ const removed = this.events.shift()!
47
+ this.removeFromIndexes(removed)
48
+ }
49
+
50
+ // 索引
51
+ this.addToIndex(this.eventsByInstruction, event.instructionId, event)
52
+ this.addToIndex(this.eventsByCorrelation, event.correlationId, event)
53
+ this.addToIndex(this.eventsByType, event.eventType, event)
54
+
55
+ // 统计
56
+ this.stats.totalEvents++
57
+ this.stats.eventCounts.set(
58
+ event.eventType,
59
+ (this.stats.eventCounts.get(event.eventType) || 0) + 1
60
+ )
61
+ this.stats.instructionCounts.set(
62
+ event.instructionType,
63
+ (this.stats.instructionCounts.get(event.instructionType) || 0) + 1
64
+ )
65
+ }
66
+
67
+ private addToIndex<K>(map: Map<K, CPUEvent[]>, key: K, event: CPUEvent): void {
68
+ if (!map.has(key)) {
69
+ map.set(key, [])
70
+ }
71
+ map.get(key)!.push(event)
72
+ }
73
+
74
+ private removeFromIndexes(event: CPUEvent): void {
75
+ // 从索引中移除(简化实现)
76
+ const instrEvents = this.eventsByInstruction.get(event.instructionId)
77
+ if (instrEvents) {
78
+ const index = instrEvents.indexOf(event)
79
+ if (index > -1) instrEvents.splice(index, 1)
80
+ }
81
+
82
+ const corrEvents = this.eventsByCorrelation.get(event.correlationId)
83
+ if (corrEvents) {
84
+ const index = corrEvents.indexOf(event)
85
+ if (index > -1) corrEvents.splice(index, 1)
86
+ }
87
+
88
+ const typeEvents = this.eventsByType.get(event.eventType)
89
+ if (typeEvents) {
90
+ const index = typeEvents.indexOf(event)
91
+ if (index > -1) typeEvents.splice(index, 1)
92
+ }
93
+ }
94
+
95
+ // ==================== 查询 API ====================
96
+
97
+ /**
98
+ * 查询:获取指令的完整事件链
99
+ */
100
+ getInstructionTrace(instructionId: string): CPUEvent[] {
101
+ return this.eventsByInstruction.get(instructionId) || []
102
+ }
103
+
104
+ /**
105
+ * 查询:获取 correlationId 的完整链路
106
+ */
107
+ getCorrelationTrace(correlationId: string): CPUEvent[] {
108
+ return this.eventsByCorrelation.get(correlationId) || []
109
+ }
110
+
111
+ /**
112
+ * 查询:按类型过滤事件
113
+ */
114
+ getEventsByType(type: CPUEventType): CPUEvent[] {
115
+ return this.eventsByType.get(type) || []
116
+ }
117
+
118
+ /**
119
+ * 查询:按指令类型过滤
120
+ */
121
+ getEventsByInstructionType(instructionType: string): CPUEvent[] {
122
+ return this.events.filter((e) => e.instructionType === instructionType)
123
+ }
124
+
125
+ /**
126
+ * 查询:按时间范围过滤
127
+ */
128
+ getEventsByTimeRange(startTime: number, endTime: number): CPUEvent[] {
129
+ return this.events.filter((e) => e.timestamp >= startTime && e.timestamp <= endTime)
130
+ }
131
+
132
+ /**
133
+ * 查询:按标签过滤
134
+ */
135
+ getEventsByTags(tags: string[]): CPUEvent[] {
136
+ return this.events.filter((e) => tags.some((tag) => e.metadata?.tags?.includes(tag)))
137
+ }
138
+
139
+ /**
140
+ * 高级查询:复杂条件
141
+ */
142
+ query(filter: {
143
+ instructionType?: string
144
+ eventType?: CPUEventType
145
+ pipelineStage?: PipelineStage
146
+ instructionStatus?: InstructionStatus
147
+ timeRange?: { start: number; end: number }
148
+ tags?: string[]
149
+ minLatency?: number
150
+ maxLatency?: number
151
+ }): CPUEvent[] {
152
+ let results = this.events
153
+
154
+ if (filter.instructionType) {
155
+ results = results.filter((e) => e.instructionType === filter.instructionType)
156
+ }
157
+
158
+ if (filter.eventType) {
159
+ results = results.filter((e) => e.eventType === filter.eventType)
160
+ }
161
+
162
+ if (filter.pipelineStage) {
163
+ results = results.filter((e) => e.pipelineStage === filter.pipelineStage)
164
+ }
165
+
166
+ if (filter.instructionStatus) {
167
+ results = results.filter((e) => e.instructionStatus === filter.instructionStatus)
168
+ }
169
+
170
+ if (filter.timeRange) {
171
+ results = results.filter(
172
+ (e) => e.timestamp >= filter.timeRange!.start && e.timestamp <= filter.timeRange!.end
173
+ )
174
+ }
175
+
176
+ if (filter.tags) {
177
+ results = results.filter((e) => filter.tags!.some((tag) => e.metadata?.tags?.includes(tag)))
178
+ }
179
+
180
+ if (filter.minLatency !== undefined) {
181
+ results = results.filter((e) => e.latency !== undefined && e.latency >= filter.minLatency!)
182
+ }
183
+
184
+ if (filter.maxLatency !== undefined) {
185
+ results = results.filter((e) => e.latency !== undefined && e.latency <= filter.maxLatency!)
186
+ }
187
+
188
+ return results
189
+ }
190
+
191
+ // ==================== 分析 API ====================
192
+
193
+ /**
194
+ * 分析:指令性能统计
195
+ */
196
+ analyzeInstructionPerformance(instructionType: string): {
197
+ count: number
198
+ successRate: number
199
+ avgLatency: number
200
+ p50: number
201
+ p95: number
202
+ p99: number
203
+ } {
204
+ const instructions = Array.from(this.eventsByInstruction.entries()).filter(
205
+ ([_, events]) => events[0]?.instructionType === instructionType
206
+ )
207
+
208
+ if (instructions.length === 0) {
209
+ return {
210
+ count: 0,
211
+ successRate: 0,
212
+ avgLatency: 0,
213
+ p50: 0,
214
+ p95: 0,
215
+ p99: 0,
216
+ }
217
+ }
218
+
219
+ const latencies: number[] = []
220
+ let successCount = 0
221
+
222
+ for (const [_, events] of instructions) {
223
+ const commitEvent = events.find((e) => e.eventType === CPUEventType.INSTRUCTION_COMMITTED)
224
+ const failEvent = events.find((e) => e.eventType === CPUEventType.INSTRUCTION_FAILED)
225
+
226
+ if (commitEvent) {
227
+ successCount++
228
+ const duration = commitEvent.timestamp - events[0].timestamp
229
+ latencies.push(duration)
230
+ } else if (failEvent) {
231
+ const duration = failEvent.timestamp - events[0].timestamp
232
+ latencies.push(duration)
233
+ }
234
+ }
235
+
236
+ latencies.sort((a, b) => a - b)
237
+
238
+ return {
239
+ count: instructions.length,
240
+ successRate: successCount / instructions.length,
241
+ avgLatency: latencies.reduce((a, b) => a + b, 0) / latencies.length || 0,
242
+ p50: this.percentile(latencies, 0.5),
243
+ p95: this.percentile(latencies, 0.95),
244
+ p99: this.percentile(latencies, 0.99),
245
+ }
246
+ }
247
+
248
+ /**
249
+ * 分析:资源冲突热点
250
+ */
251
+ analyzeResourceConflicts(): Array<{
252
+ resource: string
253
+ conflictCount: number
254
+ avgWaitTime: number
255
+ involvedInstructions: string[]
256
+ }> {
257
+ const conflicts = this.getEventsByType(CPUEventType.SCHEDULER_CONFLICT_DETECTED)
258
+
259
+ const resourceMap = new Map<
260
+ string,
261
+ { count: number; totalWait: number; instructions: Set<string> }
262
+ >()
263
+
264
+ for (const event of conflicts) {
265
+ const { conflictingResources, waitTime, conflictingInstructions } = event.payload
266
+
267
+ for (const resource of conflictingResources) {
268
+ if (!resourceMap.has(resource)) {
269
+ resourceMap.set(resource, {
270
+ count: 0,
271
+ totalWait: 0,
272
+ instructions: new Set(),
273
+ })
274
+ }
275
+
276
+ const entry = resourceMap.get(resource)!
277
+ entry.count++
278
+ entry.totalWait += waitTime
279
+ conflictingInstructions.forEach((id: string) => entry.instructions.add(id))
280
+ }
281
+ }
282
+
283
+ return Array.from(resourceMap.entries())
284
+ .map(([resource, data]) => ({
285
+ resource,
286
+ conflictCount: data.count,
287
+ avgWaitTime: data.totalWait / data.count,
288
+ involvedInstructions: Array.from(data.instructions),
289
+ }))
290
+ .sort((a, b) => b.conflictCount - a.conflictCount)
291
+ }
292
+
293
+ /**
294
+ * 分析:乐观更新回滚率
295
+ */
296
+ analyzeOptimisticRollbackRate(): {
297
+ totalOptimistic: number
298
+ rollbackCount: number
299
+ rollbackRate: number
300
+ byInstructionType: Record<string, { total: number; rollbacks: number; rate: number }>
301
+ } {
302
+ const appliedEvents = this.getEventsByType(CPUEventType.OPTIMISTIC_APPLIED)
303
+ const rolledBackEvents = this.getEventsByType(CPUEventType.OPTIMISTIC_ROLLED_BACK)
304
+
305
+ const byType: Record<string, { total: number; rollbacks: number; rate: number }> = {}
306
+
307
+ // 统计每种指令类型的乐观更新和回滚
308
+ for (const event of appliedEvents) {
309
+ if (!byType[event.instructionType]) {
310
+ byType[event.instructionType] = { total: 0, rollbacks: 0, rate: 0 }
311
+ }
312
+ byType[event.instructionType].total++
313
+ }
314
+
315
+ for (const event of rolledBackEvents) {
316
+ if (!byType[event.instructionType]) {
317
+ byType[event.instructionType] = { total: 0, rollbacks: 0, rate: 0 }
318
+ }
319
+ byType[event.instructionType].rollbacks++
320
+ }
321
+
322
+ // 计算回滚率
323
+ for (const type in byType) {
324
+ byType[type].rate = byType[type].rollbacks / byType[type].total
325
+ }
326
+
327
+ return {
328
+ totalOptimistic: appliedEvents.length,
329
+ rollbackCount: rolledBackEvents.length,
330
+ rollbackRate: rolledBackEvents.length / appliedEvents.length || 0,
331
+ byInstructionType: byType,
332
+ }
333
+ }
334
+
335
+ /**
336
+ * 分析:流水线吞吐量
337
+ */
338
+ analyzeThroughput(timeWindowMs: number = 60000): {
339
+ instructionsPerSecond: number
340
+ eventsPerSecond: number
341
+ avgPipelineUtilization: number
342
+ } {
343
+ const now = Date.now()
344
+ const startTime = now - timeWindowMs
345
+
346
+ const recentEvents = this.getEventsByTimeRange(startTime, now)
347
+ const instructionIds = new Set(recentEvents.map((e) => e.instructionId))
348
+
349
+ return {
350
+ instructionsPerSecond: (instructionIds.size / timeWindowMs) * 1000,
351
+ eventsPerSecond: (recentEvents.length / timeWindowMs) * 1000,
352
+ avgPipelineUtilization: 0, // TODO: 计算流水线利用率
353
+ }
354
+ }
355
+
356
+ /**
357
+ * 工具:计算百分位数
358
+ */
359
+ private percentile(values: number[], p: number): number {
360
+ if (values.length === 0) return 0
361
+ const index = Math.ceil(values.length * p) - 1
362
+ return values[index] || 0
363
+ }
364
+
365
+ /**
366
+ * 快速统计(用于 Pipeline status)
367
+ */
368
+ getQuickStats(): { totalCompleted: number; totalFailed: number; totalCancelled: number } {
369
+ let totalCompleted = 0
370
+ let totalFailed = 0
371
+ let totalCancelled = 0
372
+
373
+ // 遍历所有指令,统计成功、失败和取消次数
374
+ for (const events of this.eventsByInstruction.values()) {
375
+ const lastEvent = events[events.length - 1]
376
+ if (lastEvent?.eventType === CPUEventType.INSTRUCTION_COMMITTED) {
377
+ totalCompleted++
378
+ } else if (lastEvent?.eventType === CPUEventType.INSTRUCTION_FAILED) {
379
+ totalFailed++
380
+ } else if (lastEvent?.eventType === CPUEventType.INSTRUCTION_CANCELLED) {
381
+ totalCancelled++
382
+ }
383
+ }
384
+
385
+ return { totalCompleted, totalFailed, totalCancelled }
386
+ }
387
+
388
+ /**
389
+ * 获取统计信息
390
+ */
391
+ getStats() {
392
+ return {
393
+ ...this.stats,
394
+ ...this.getQuickStats(), // 🔥 包含快速统计
395
+ totalInstructions: this.eventsByInstruction.size,
396
+ totalCorrelations: this.eventsByCorrelation.size,
397
+ storageUsage: this.events.length,
398
+ maxStorage: this.maxEvents,
399
+ }
400
+ }
401
+
402
+ /**
403
+ * 导出数据(用于离线分析)
404
+ */
405
+ exportData(filter?: any): {
406
+ events: CPUEvent[]
407
+ stats: any
408
+ exportTime: number
409
+ } {
410
+ const events = filter ? this.query(filter) : this.events
411
+
412
+ return {
413
+ events,
414
+ stats: this.getStats(),
415
+ exportTime: Date.now(),
416
+ }
417
+ }
418
+
419
+ /**
420
+ * 清空数据
421
+ */
422
+ clear(): void {
423
+ this.events = []
424
+ this.eventsByInstruction.clear()
425
+ this.eventsByCorrelation.clear()
426
+ this.eventsByType.clear()
427
+ this.stats = {
428
+ totalEvents: 0,
429
+ eventCounts: new Map(),
430
+ instructionCounts: new Map(),
431
+ }
432
+ }
433
+ }
434
+
435
+ export const cpuLogger = new CPULogger()