代码之家  ›  专栏  ›  技术社区  ›  Megidd

用索引直接访问替换循环(以及循环中的条件)

  •  -1
  • Megidd  · 技术社区  · 5 年前

    我有一个for循环,循环中有一个条件,可以在 index :

    // uint index = ...
    // const float *bufferPtr = ...
    // uint stride = ...
    // uint vertexCount = ...
    
    for (uint i = 0; i < vertexCount; i++) {
        float xVal = *bufferPtr++;
        float yVal = *bufferPtr++;
        float zVal = *bufferPtr++;
        bufferPtr += stride;
        if (i == index) {
            qDebug() << "Vertex coord: " << xVal << " , " << yVal << " , " << zVal;
        }
    }
    

    我试图用索引直接访问替换for循环(及其内部条件):

    float xVal = *(bufferPtr + index * stride + 0);
    float yVal = *(bufferPtr + index * stride + 1);
    float zVal = *(bufferPtr + index * stride + 2);
    qDebug() << "Vertex coord without loop: " << xVal << " , " << yVal << " , " << zVal;
    

    但是输出日志给了我 不同的 结果:

    Vertex coord:  14.574  ,  -8.236  ,  7.644
    Vertex coord without loop:  20.67  ,  -19.098  ,  18.536
    Vertex coord:  14.552  ,  -8.024  ,  7.842
    Vertex coord without loop:  -0.361096  ,  0.109164  ,  0.926117
    Vertex coord:  14.722  ,  -8.18  ,  7.842
    Vertex coord without loop:  20.648  ,  -19.052  ,  18.522
    

    我不明白为什么结果不同:(


    修理

    正如@LanceDeGate answer所建议的,通过减少 stride 通过 3 循环之前:

    
    stride = stride - 3; // Three floats per vertex
    
    for (uint i = 0; i < vertexCount; i++) {
        float xVal = *bufferPtr++;
        float yVal = *bufferPtr++;
        float zVal = *bufferPtr++;
        bufferPtr += stride;
        if (i == index) {
            qDebug() << "Vertex coord: " << xVal << " , " << yVal << " , " << zVal;
        }
    }
    

    现在日志是一样的:

    Vertex coord:  -0.522632  ,  -0.803892  ,  -9.02102
    Vertex coord without loop:  -0.522632  ,  -0.803892  ,  -9.02102
    Vertex coord:  -0.39095  ,  -2.04955  ,  -8.91668
    Vertex coord without loop:  -0.39095  ,  -2.04955  ,  -8.91668
    Vertex coord:  -0.259928  ,  -0.804899  ,  -9.03231
    Vertex coord without loop:  -0.259928  ,  -0.804899  ,  -9.03231
    
    3 回复  |  直到 5 年前
        1
  •  1
  •   Lance DeGate    5 年前

    也许是因为 大步走 在三个“bufferPtr++”之后,添加到bufferPtr。

    也许这就是你的意思:

    float xVal = *bufferPtr;
    float yVal = *(bufferPtr+1);
    float zVal = *(bufferPtr+2);
    bufferPtr += stride;
    

    float xVal = *bufferPtr++;
    float yVal = *bufferPtr++;
    float zVal = *bufferPtr++;
    bufferPtr += (stride-3);
    
        2
  •  1
  •   Klaus    5 年前

    第一个提示:

    如果可能的话,请提供一个每个人都可以编译的完整示例。这需要一些时间来启动和运行你的代码。。。

    好吧,据我所知你的!代码是这样的:

    float var[]= { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    size_t elements = sizeof(var)/sizeof(float);
    int stride = 2;
    int vertexCount = elements/(3+stride);
    
    void f( float* bufferPtr, int index )
    {
        for (uint i = 0; i < vertexCount; i++)
        {
            float xVal = *bufferPtr++;
            float yVal = *bufferPtr++;
            float zVal = *bufferPtr++;
            bufferPtr += stride;
            if (i == index) {
            std::cout << "Vertex coord: " << xVal << " , " << yVal << " , " << zVal << std::endl;
            }
        }
    }
    

    可以简化为:

    void f2( float* bufferPtr, int index )
    {   
        struct Data
        {
            float x;
            float y;
            float z;
            float dummy[2]; // stride
        };
    
       Data& d = (reinterpret_cast<Data*>(bufferPtr))[index];
       std::cout << "Vertex coord: " << d.x << " " << d.y << " " << d.z << std::endl;
    }   
    
    
    int main()
    {   
        f( var, 2 );
        f2( var, 2 );
    }  
    
        3
  •  1
  •   borizzzzz    5 年前

    通过以下测试用例,我得到了正确的结果:

    #include <iostream>
    int main()
    {
      float tabla[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
      unsigned int index = 0;
      const float *bufferPtr = &tabla[0];
      unsigned int stride = 2;
      unsigned int vertexCount = 2;
    
      for (uint i = 0; i < vertexCount; i++) {
        float xVal = *bufferPtr++;
        float yVal = *bufferPtr++;
        float zVal = *bufferPtr++;
        bufferPtr += stride;
        if (i == index) {
          std::cout << "Vertex coord: " << xVal << " , " << yVal << " , " << zVal << std::endl;
        }
      }
      const float *bufferPtr2 = &tabla[0];
      float xVal2 = *(bufferPtr2 + index * stride + 0);
      float yVal2 = *(bufferPtr2 + index * stride + 1);
      float zVal2 = *(bufferPtr2 + index * stride + 2);
      std::cout << "Vertex coord without loop: " << xVal2 << " , " << yVal2 << " , " << zVal2 << std::endl;
      return 0;
    }
    

    输出:

    Vertex coord: 0 , 1 , 2
    Vertex coord without loop: 0 , 1 , 2
    

    我根本没有改变你的代码。唯一的区别是,我在一个主函数中添加了两个测试,显然使用了不同的缓冲区指针( bufferPtr2 )我用表格的第一个地址初始化 tabla .您确定在尝试其他方法之前重置了指针吗?很难说,因为您只提供了代码片段。