Есть ли отступы для структуры поплавков? - PullRequest
0 голосов
/ 26 января 2019

Мне нужно создать кусок памяти, плотно заполненный поплавками.Но вместо создания вектора чисел с плавающей точкой я хотел бы создать вектор, в котором каждый член является группой связанных чисел с плавающей точкой:

struct FloatStruct
{
    FloatStruct() : 
        a(1.f), b(10.f), c(100.f), d(1000.f), e(10000.f) { }

    float a;
    float b;
    float c;
    float d;
    float e;
};


int main()
{
    std::vector<FloatStruct> fvec(100);

    auto pf = &fvec[0].a;

    for(int i = 0; i < 500; ++i)
        std::cout << *pf++ << "\n";
}

Вышеприведенный код, видимо, отлично работает на моей архитектуре с MSVC (итакже на некоторых онлайн-компиляторах с GCC или Clang).Поплавки все плотно упакованы.Но я беспокоюсь о переносимости этого кода.Может быть, в какую-то архитектуру можно добавить отступы, и это может нарушить сжатие памяти.

Устанавливает ли стандарт какие-либо гарантии в таком случае?

1 Ответ

0 голосов
/ 26 января 2019

Чтобы ответить на ваш вопрос, да, есть платформы, где это может вызвать проблемы.Поскольку вы специально упоминаете, что оно будет отправлено на графический процессор, это может быть проблематично для некоторых архитектур.Недавно я столкнулся с этой проблемой с Metal на macOS, где я хотел уменьшить свои данные на 25%, поэтому отправлял только (x, y, z) вместо (x, y, z, 1.0) для моих координат текстуры и результата.было то, что все координаты были выключены.(Я полагаю, что проблема заключалась в том, что архитектура GPU предполагала определенное заполнение, которое не обеспечивала архитектура CPU, хотя я думаю, что это дало бы аналогично плохие результаты, если бы было верно обратное.)

Решение для перекрестногоСовместимость платформы, вероятно, заключается в определении макроса, обеспечивающего правильное заполнение для каждого используемого компилятораЗатем при определении структуры данных используйте этот макрос, чтобы получить правильное заполнение.Таким образом, это выглядело бы примерно так:

#if MSVC
    #define PACK_TIGHTLY <MSVC-specific definition of tight packing>
    #define END_PACK_TIGHTLY <MSVC-specific definition of ending tight packing>
#elif  Clang
    #define PACK_TIGHTLY <clang-specific definition of tight packing>
    #define END_PACK_TIGHTLY <clang-specific definition of ending tight packing>
#elif
    // ... etc. for other platforms you want to support
#endif

Тогда при определении вашего struct вы бы сделали что-то вроде:

PACK_TIGHTLY
struct FloatStruct
{
    FloatStruct() : 
        a(1.f), b(10.f), c(100.f), d(1000.f), e(10000.f) { }

    float a;
    float b;
    float c;
    float d;
    float e;
};
END_PACK_TIGHTLY
...