可以计算Shader算法的时间复杂度吗?
It`s possible to calculate time complexity of Shader algorithm?
我目前正在参加一个算法分析 class,我们被分配了小组作业。教授要求我们选择计算机科学中的某个领域,选择一种算法并证明渐近极限(至少O(N))。
所以我和我的同事选择了做一个计算机图形算法,更具体地说是一个光照体积算法。
但是算法分析书上分析的代码都是跑在CPU上的。 OpenGL 生成的代码在 GPU 上运行,不能保证线性度,因为它是由其他几个 CPUs 运行 并行组成的。
该行为会影响计算吗?有人可以帮我弄清楚从哪里开始吗?
这段代码摘自GPU Gems 3:
Volumetric Light Scattering as a Post-Process.
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
// Calculate vector from pixel to light source in screen space.
half2 deltaTexCoord = (texCoord - ScreenLightPos.xy);
// Divide by number of samples and scale by control factor.
deltaTexCoord *= 1.0f / NUM_SAMPLES * Density;
// Store initial sample.
half3 color = tex2D(frameSampler, texCoord);
// Set up illumination decay factor.
half illuminationDecay = 1.0f;
// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
for (int i = 0; i < NUM_SAMPLES; i++)
{
// Step sample location along ray.
texCoord -= deltaTexCoord;
// Retrieve sample at new location.
half3 sample = tex2D(frameSampler, texCoord);
// Apply sample attenuation scale/decay factors.
sample *= illuminationDecay * Weight;
// Accumulate combined color.
color += sample;
// Update exponential decay factor.
illuminationDecay *= Decay;
}
// Output final color with a further scale control factor.
return float4( color * Exposure, 1);
}
我认为渐近极限是样本的函数。
还需要考虑的是生成着色器所需的 4 个物理方程。在此先感谢所有社区的帮助!
算法的复杂度不会随着处理元素的数量而改变(对于有限数量的处理器)。多项式时间算法是多项式时间,无论是在 CPU 还是 GPU 上。换句话说,n2 与 (n/320)2 没有区别,因为 "n" 接近无穷大。
算法的复杂度没有改变; 执行时间确实如此。但很多复杂性都是如此。快速排序和合并排序具有相同的 nLog(n) 复杂度,但实际上快速排序平均更快。
渐近极限并不是性能的最终结果。
所有代码行都意味着执行时间恒定(它们并不意味着循环或递归调用或类似的东西)。但是,循环内的行被执行了 NUM_SAMPLES 次。因此,一次着色器调用的执行时间将为:
O(NumSamples)
由于此着色器每个像素执行一次,因此总执行时间将为:
O(NumSamples * ResolutionX * ResolutionY)
记住 Nicol Bolas 是对的,算法的复杂度没有改变,如果在 CPU 上执行也是一样的,但是硬件相关的问题会更慢.
在更深入的分析中,您可以分析每个 GPU 内核的使用情况和 CPU 的加速,但在这个简单的代码中...这并不重要,因为使用情况可能非常接近到 100%。无论如何,要对此进行分析,您需要了解 GPU 硬件架构和一般算法成本。
uniform float exposure;
uniform float decay;
uniform float density;
uniform float weight;
uniform vec2 lightPositionOnScreen;
uniform sampler2D myTexture;
const int NUM_SAMPLES = 100 ;
void main()
{
C1 vec2 deltaTextCoord=vec2(gl_TexCoord[0].st-lightPositionOnScreen.xy);
C2 vec2 textCoo = gl_TexCoord[0].st;
C3 deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
C4 float illuminationDecay = 1.0;
n for(int i=0; i < NUM_SAMPLES ; i++) {
C5 textCoo -= deltaTextCoord;
C6 vec4 sample = texture2D(myTexture, textCoo );
C7 sample *= illuminationDecay * weight;
C8 gl_FragColor += sample;
C9 illuminationDecay *= decay;
}
C10 gl_FragColor *= exposure;
}
f(n) =∑_(i=0)^n〖(C_5+ C_6+ C_7+ C_8+ C_9)〗 + C_1 + C_2 + C_3 + C_4 + C_10
(C_5+ C_6+ C_7+ C_8+ C_9 )=K_1
(C_1 + C_2 + C_3 + C_4 + C_10)=K_2
因此:
f(n)= Cp* K_1*n+ K_2
作为Cp像素数。
这是
f(n)= θ(n) for each pixel.
@dv1729 评论对大学作业的开发过程很有帮助。
这证明计算机图形算法分析可能非常具有欺骗性,因为我们都知道这种 post 处理在硬件上有多难,但是查看代码向我们展示了一个渐近极限,它确实非常低的。这里的常量可能非常高,基于物理的体积光散射背后的深奥数学可能会被忽视。
我目前正在参加一个算法分析 class,我们被分配了小组作业。教授要求我们选择计算机科学中的某个领域,选择一种算法并证明渐近极限(至少O(N))。
所以我和我的同事选择了做一个计算机图形算法,更具体地说是一个光照体积算法。
但是算法分析书上分析的代码都是跑在CPU上的。 OpenGL 生成的代码在 GPU 上运行,不能保证线性度,因为它是由其他几个 CPUs 运行 并行组成的。
该行为会影响计算吗?有人可以帮我弄清楚从哪里开始吗?
这段代码摘自GPU Gems 3: Volumetric Light Scattering as a Post-Process.
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
// Calculate vector from pixel to light source in screen space.
half2 deltaTexCoord = (texCoord - ScreenLightPos.xy);
// Divide by number of samples and scale by control factor.
deltaTexCoord *= 1.0f / NUM_SAMPLES * Density;
// Store initial sample.
half3 color = tex2D(frameSampler, texCoord);
// Set up illumination decay factor.
half illuminationDecay = 1.0f;
// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
for (int i = 0; i < NUM_SAMPLES; i++)
{
// Step sample location along ray.
texCoord -= deltaTexCoord;
// Retrieve sample at new location.
half3 sample = tex2D(frameSampler, texCoord);
// Apply sample attenuation scale/decay factors.
sample *= illuminationDecay * Weight;
// Accumulate combined color.
color += sample;
// Update exponential decay factor.
illuminationDecay *= Decay;
}
// Output final color with a further scale control factor.
return float4( color * Exposure, 1);
}
我认为渐近极限是样本的函数。 还需要考虑的是生成着色器所需的 4 个物理方程。在此先感谢所有社区的帮助!
算法的复杂度不会随着处理元素的数量而改变(对于有限数量的处理器)。多项式时间算法是多项式时间,无论是在 CPU 还是 GPU 上。换句话说,n2 与 (n/320)2 没有区别,因为 "n" 接近无穷大。
算法的复杂度没有改变; 执行时间确实如此。但很多复杂性都是如此。快速排序和合并排序具有相同的 nLog(n) 复杂度,但实际上快速排序平均更快。
渐近极限并不是性能的最终结果。
所有代码行都意味着执行时间恒定(它们并不意味着循环或递归调用或类似的东西)。但是,循环内的行被执行了 NUM_SAMPLES 次。因此,一次着色器调用的执行时间将为:
O(NumSamples)
由于此着色器每个像素执行一次,因此总执行时间将为:
O(NumSamples * ResolutionX * ResolutionY)
记住 Nicol Bolas 是对的,算法的复杂度没有改变,如果在 CPU 上执行也是一样的,但是硬件相关的问题会更慢.
在更深入的分析中,您可以分析每个 GPU 内核的使用情况和 CPU 的加速,但在这个简单的代码中...这并不重要,因为使用情况可能非常接近到 100%。无论如何,要对此进行分析,您需要了解 GPU 硬件架构和一般算法成本。
uniform float exposure;
uniform float decay;
uniform float density;
uniform float weight;
uniform vec2 lightPositionOnScreen;
uniform sampler2D myTexture;
const int NUM_SAMPLES = 100 ;
void main()
{
C1 vec2 deltaTextCoord=vec2(gl_TexCoord[0].st-lightPositionOnScreen.xy);
C2 vec2 textCoo = gl_TexCoord[0].st;
C3 deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
C4 float illuminationDecay = 1.0;
n for(int i=0; i < NUM_SAMPLES ; i++) {
C5 textCoo -= deltaTextCoord;
C6 vec4 sample = texture2D(myTexture, textCoo );
C7 sample *= illuminationDecay * weight;
C8 gl_FragColor += sample;
C9 illuminationDecay *= decay;
}
C10 gl_FragColor *= exposure;
}
f(n) =∑_(i=0)^n〖(C_5+ C_6+ C_7+ C_8+ C_9)〗 + C_1 + C_2 + C_3 + C_4 + C_10
(C_5+ C_6+ C_7+ C_8+ C_9 )=K_1
(C_1 + C_2 + C_3 + C_4 + C_10)=K_2
因此:
f(n)= Cp* K_1*n+ K_2
作为Cp像素数。
这是
f(n)= θ(n) for each pixel.
@dv1729 评论对大学作业的开发过程很有帮助。
这证明计算机图形算法分析可能非常具有欺骗性,因为我们都知道这种 post 处理在硬件上有多难,但是查看代码向我们展示了一个渐近极限,它确实非常低的。这里的常量可能非常高,基于物理的体积光散射背后的深奥数学可能会被忽视。