1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
| private instructionCosts: Map<string, InstructionCost> = new Map(); interface InstructionCost { aluCost: number; textureCost: number; bandwidthCost: number; registerPressure: number; category: 'math' | 'texture' | 'control' | 'memory'; } interface ShaderAnalysisResult { totalInstructions: number; aluInstructions: number; textureInstructions: number; controlInstructions: number; estimatedCycles: number; registerUsage: number; complexityScore: number; optimizationOpportunities: OptimizationOpportunity[]; } interface OptimizationOpportunity { type: 'reduce_alu' | 'reduce_texture' | 'reduce_branching' | 'reduce_precision' | 'vectorize'; description: string; impact: 'high' | 'medium' | 'low'; implementation: string; } constructor() { this.initializeInstructionCosts(); } private initializeInstructionCosts(): void { this.instructionCosts.set('add', { aluCost: 1, textureCost: 0, bandwidthCost: 0, registerPressure: 0.1, category: 'math' }); this.instructionCosts.set('mul', { aluCost: 1, textureCost: 0, bandwidthCost: 0, registerPressure: 0.1, category: 'math' }); this.instructionCosts.set('div', { aluCost: 4, textureCost: 0, bandwidthCost: 0, registerPressure: 0.2, category: 'math' }); this.instructionCosts.set('sqrt', { aluCost: 3, textureCost: 0, bandwidthCost: 0, registerPressure: 0.2, category: 'math' }); this.instructionCosts.set('sin', { aluCost: 8, textureCost: 0, bandwidthCost: 0, registerPressure: 0.3, category: 'math' }); this.instructionCosts.set('cos', { aluCost: 8, textureCost: 0, bandwidthCost: 0, registerPressure: 0.3, category: 'math' }); this.instructionCosts.set('pow', { aluCost: 12, textureCost: 0, bandwidthCost: 0, registerPressure: 0.4, category: 'math' }); this.instructionCosts.set('texture2D', { aluCost: 1, textureCost: 4, bandwidthCost: 8, registerPressure: 0.2, category: 'texture' }); this.instructionCosts.set('textureCube', { aluCost: 1, textureCost: 6, bandwidthCost: 12, registerPressure: 0.3, category: 'texture' }); this.instructionCosts.set('texture2DLod', { aluCost: 2, textureCost: 6, bandwidthCost: 10, registerPressure: 0.3, category: 'texture' }); this.instructionCosts.set('for', { aluCost: 3, textureCost: 0, bandwidthCost: 0, registerPressure: 0.2, category: 'control' }); this.instructionCosts.set('discard', { aluCost: 5, textureCost: 0, bandwidthCost: 0, registerPressure: 0.1, category: 'control' }); } public analyzeShaderSource(vertexSource: string, fragmentSource: string): ShaderAnalysisResult { console.log('🔍 分析着色器复杂�?..'); const vertexAnalysis = this.analyzeShaderStage(vertexSource, 'vertex'); const fragmentAnalysis = this.analyzeShaderStage(fragmentSource, 'fragment'); const result: ShaderAnalysisResult = { totalInstructions: vertexAnalysis.instructions + fragmentAnalysis.instructions, aluInstructions: vertexAnalysis.aluInstructions + fragmentAnalysis.aluInstructions, textureInstructions: vertexAnalysis.textureInstructions + fragmentAnalysis.textureInstructions, controlInstructions: vertexAnalysis.controlInstructions + fragmentAnalysis.controlInstructions, estimatedCycles: Math.max(vertexAnalysis.estimatedCycles, fragmentAnalysis.estimatedCycles), complexityScore: this.calculateComplexityScore(vertexAnalysis, fragmentAnalysis), optimizationOpportunities: [ ...vertexAnalysis.optimizations, ...fragmentAnalysis.optimizations ] }; console.log('📊 着色器分析结果:', result); return result; } private analyzeShaderStage(source: string, stage: 'vertex' | 'fragment'): StageAnalysis { const lines = source.split('\n'); let instructions = 0; let aluInstructions = 0; let textureInstructions = 0; let controlInstructions = 0; let estimatedCycles = 0; let registerUsage = 0; const optimizations: OptimizationOpportunity[] = []; for (const line of lines) { const trimmedLine = line.trim(); instructions++; if (this.containsTextureOperation(trimmedLine)) { textureInstructions++; estimatedCycles += 4; registerUsage += 0.2; optimizations.push({ type: 'reduce_texture', description: '可以合并或减少纹理采�?, impact: 'medium', implementation: '使用atlas纹理或减少采样次�? }); } } if (this.containsMathOperation(trimmedLine)) { aluInstructions++; estimatedCycles += this.estimateMathCycles(trimmedLine); registerUsage += 0.1; optimizations.push({ type: 'reduce_alu', description: '可以简化数学计�?, impact: 'medium', implementation: '使用查找表或简化算�? }); } } if (this.containsControlFlow(trimmedLine)) { controlInstructions++; estimatedCycles += 2; registerUsage += 0.15; type: 'reduce_branching', description: '可以减少条件分支', impact: 'high', implementation: '使用step/lerp函数替代if语句' }); } } return { instructions, aluInstructions, textureInstructions, controlInstructions, estimatedCycles, registerUsage, optimizations }; } private containsTextureOperation(line: string): boolean { return /texture2D|textureCube|texture2DLod|texture2DProj/.test(line); } private containsMathOperation(line: string): boolean { return /\+|\-|\*|\/|pow|sqrt|sin|cos|tan|normalize|dot|cross|length/.test(line); } private containsControlFlow(line: string): boolean { return /\bif\b|\bfor\b|\bwhile\b|\bdiscard\b/.test(line); } private estimateMathCycles(line: string): number { let cycles = 1; if (line.includes('pow')) cycles += 12; else if (line.includes('sin') || line.includes('cos')) cycles += 8; else if (line.includes('sqrt')) cycles += 3; else if (line.includes('/')) cycles += 4; else if (line.includes('normalize')) cycles += 4; return cycles; } private calculateComplexityScore(vertexAnalysis: StageAnalysis, fragmentAnalysis: StageAnalysis): number { const vertexScore = vertexAnalysis.estimatedCycles / 10; const fragmentScore = fragmentAnalysis.estimatedCycles / 20; return Math.min(100, vertexScore + fragmentScore); } public generateOptimizationReport(analysis: ShaderAnalysisResult): string { let report = '🔍 着色器性能分析报告\n'; report += '=' * 40 + '\n'; report += `总指令数: ${analysis.totalInstructions}\n`; report += `ALU指令: ${analysis.aluInstructions}\n`; report += `纹理指令: ${analysis.textureInstructions}\n`; report += `控制流指�? ${analysis.controlInstructions}\n`; report += `预估周期�? ${analysis.estimatedCycles}\n`; report += `寄存器使用率: ${(analysis.registerUsage * 100).toFixed(1)}%\n`; report += `复杂度评�? ${analysis.complexityScore.toFixed(1)}/100\n\n`; if (analysis.complexityScore > 70) { report += '⚠️ 着色器复杂度较高,建议优化\n\n'; } else if (analysis.complexityScore > 50) { report += '💡 着色器复杂度中等,可考虑优化\n\n'; } else { report += '�?着色器复杂度良好\n\n'; } if (analysis.optimizationOpportunities.length > 0) { report += '🔧 优化建议:\n'; analysis.optimizationOpportunities.forEach((opt, index) => { report += `${index + 1}. [${opt.impact.toUpperCase()}] ${opt.description}\n`; report += ` 实现方式: ${opt.implementation}\n\n`; }); } return report; } }
interface StageAnalysis { instructions: number; aluInstructions: number; textureInstructions: number; controlInstructions: number; estimatedCycles: number; registerUsage: number; optimizations: OptimizationOpportunity[]; }
|