Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 加速变换计算_C++_Opengl_Opencl_Glm Math - Fatal编程技术网

C++ 加速变换计算

C++ 加速变换计算,c++,opengl,opencl,glm-math,C++,Opengl,Opencl,Glm Math,我正在编程一个OpenGL3 2D引擎。 目前,我正在努力解决一个瓶颈。因此,请提供AMD探查器的以下输出: 数据是用几千个精灵制作的 但是,在50000个精灵时,testapp在5 fps时已经无法使用 这表明,我的瓶颈是我使用的转换函数。 这就是相应的功能: void NLBoundingBox::applyTransform(NLVertexData*顶点) { if(needsTransform()) { //应用矩阵 对于(int i=0;i我要做的第一件事是在进入for循环之前将

我正在编程一个OpenGL3 2D引擎。 目前,我正在努力解决一个瓶颈。因此,请提供AMD探查器的以下输出:

数据是用几千个精灵制作的

但是,在50000个精灵时,testapp在5 fps时已经无法使用

这表明,我的瓶颈是我使用的转换函数。 这就是相应的功能:

void NLBoundingBox::applyTransform(NLVertexData*顶点)
{
if(needsTransform())
{
//应用矩阵

对于(int i=0;i我要做的第一件事是在进入for循环之前将旋转矩阵和变换矩阵连接成一个矩阵……这样,你就不会在每个for循环上计算两个矩阵乘法和一个向量;相反,你只需要将一个向量和矩阵相乘。其次,你可能需要研究展开循环,然后使用更高的优化级别进行编译(在
g++
上,我至少会使用
-O2
,但我不熟悉MSVC,因此您必须自己翻译该优化级别)。这样可以避免代码中的分支可能产生的任何开销,尤其是在缓存刷新时。最后,如果您还没有研究过它,请检查执行一些SSE优化,因为您正在处理向量

更新:我将添加最后一个涉及线程的想法…基本上是在执行线程时对顶点进行流水线处理。例如,假设您有一台具有八个可用CPU线程的机器(即,具有超线程的四核)。为顶点管道处理设置六个线程,并使用非锁定的单个使用者/生产者队列在管道的各个阶段之间传递消息。每个阶段将转换六个成员顶点数组中的单个成员。我猜可能有一组六个成员顶点数组,因此在通过管道,您可以非常高效地处理流,并避免使用互斥锁和其他锁定信号量等。有关快速非锁定单生产者/消费者队列的更多信息


更新2:您只有一个双核处理器……所以放弃管道想法,因为每个线程都在争夺CPU资源,这会遇到瓶颈。

循环内的分配可能是个问题,但我不熟悉库。将其移到for循环外,然后手动执行字段分配lly可能会有所帮助。将转换移出循环也会有所帮助

编辑:

这更符合我的想法

// Apply Matrix
glm::vec4 transformed;
glm::mat4 translation = m_rotation * m_translation;
for ( int i=0; i<6; i++ )
{
    transformed.x = vertices[i].x;
    transformed.y = vertices[i].y;
    transformed.z = vertices[i].z;
    transformed.w = 1.f; // ?
    /* I can't find docs, but assume they have an in-place multiply
    transformed.mult(translation);
    // */
    vertices[i].x = transformed.x;
    vertices[i].y = transformed.y;
}
//应用矩阵
glm::vec4转化;
glm::mat4平移=m_旋转*m_平移;
对于(int i=0;i
我不能在着色器中这样做,因为我一次批处理所有精灵。这意味着,我必须使用CPU来计算变换

这听起来像是你做的过早优化,假设批处理是你能做的最重要的事情,因此你围绕着最少的绘制调用来构建渲染器。现在它又回来咬你了

你需要做的不是减少批处理。你需要有正确的批处理数量。你知道当你放弃GPU顶点变换而代之以CPU变换时,你在批处理方面走得太远了

正如DatenWalf所建议的,您需要获得一些实例来将转换恢复到GPU上。但即使如此,您也需要撤销一些过度的批处理。您还没有谈到要渲染什么样的场景(顶部带有精灵的tilemaps、大粒子系统等),所以很难知道该提出什么建议


此外,GLM是一个很好的数学库,但它不是为实现最高性能而设计的。如果我需要在CPU上每帧变换300000个顶点,通常我不会使用它。

如果你坚持在CPU上进行计算,你应该自己进行计算

现在,您正在2D环境中使用4x4矩阵,其中一个2x2矩阵用于旋转,一个简单向量用于平移就足够了。这就是旋转的4个乘法和4个加法,以及平移的两个加法

如果你绝对需要两个矩阵(因为你需要结合平移和旋转),它仍然比你现在拥有的少很多。但是你也可以“手动”通过移动向量的位置,旋转,然后再把它移回来,这可能比乘法快一点,尽管我不确定


与那些4x4矩阵现在所做的操作相比,这要少得多。

这是优化二进制文件中的一个配置文件:它并没有真正将其删除。此外,我还将这两个矩阵中的多个移出了循环(我如何监督它-)但是,它仍然没有真正的帮助。有了50k的精灵,每一帧都在移动和旋转,我赢得了一帧和两个ms。没什么大不了的。我还禁用了RTTI。很遗憾听到你只得到了一个fps…你在什么样的机器上运行这个?你的旋转和变换矩阵是否足够静态,以至于你实际上可以c计算两个矩阵的乘法值(即,在实际的
NboundingBox
类实例中,仅将它们相乘一次)?你可以缓存任何其他值,比如转换本身吗?AMD5200 DualCore,带有ATI890HD 1GB RAM。不,我不能进一步缓存它。m_旋转和m_平移是井旋转和移动的矩阵,在这个测试用例中,每个精灵都被移动和旋转以进行压力测试。每个精灵都有自己的转换和位置ofc。当它们完全不移动或旋转时,我有大约50 fps没有vsync。什么视频卡是ATI890HD?…顺便说一句,只有双核,你可以尝试管道,但会有一些争用,
// Apply Matrix
glm::vec4 transformed;
glm::mat4 translation = m_rotation * m_translation;
for ( int i=0; i<6; i++ )
{
    transformed.x = vertices[i].x;
    transformed.y = vertices[i].y;
    transformed.z = vertices[i].z;
    transformed.w = 1.f; // ?
    /* I can't find docs, but assume they have an in-place multiply
    transformed.mult(translation);
    // */
    vertices[i].x = transformed.x;
    vertices[i].y = transformed.y;
}
glm::vec4 transformed[6];
for (size_t i = 0; i < 6; i++) {
    transformed[i].x = vertices[i].x;
    transformed[i].y = vertices[i].y;
    transformed[i].z = vertices[i].z;
    transformed.w = 1.f; // ?
}
glm::mat4 translation = m_rotation * m_translation;
for (size_t i = 0; i < 6; i++) {
    /* I can't find docs, but assume they have an in-place multiply
    transformed.mult(translation);
    // */
}
for (size_t i = 0; i < 6; i++) {
    vertices[i].x = transformed[i].x;
    vertices[i].y = transformed[i].y;
}