小编Ego*_*gor的帖子

DirectX和OpenGL中的内存障碍

我试图在DirectX和OpenGL中整理内存屏障功能.我的最终目标是在GLSL中实现HLSL内存屏障功能.我发现DX和GL的文档都相当模糊.HLSL中有6个同步例程:

  • GroupMemoryBarrier()
  • GroupMemoryBarrierWithGroupSync()
  • DeviceMemoryBarrier()
  • DeviceMemoryBarrierWithGroupSync()
  • AllMemoryBarrier()
  • AllMemoryBarrierWithGroupSync()

看起来我只是真正理解WithGroupSync结尾意味着"阻止一组中所有线程的执行,直到所有线程都达到此调用".我几乎100%确定这是barrier()GLSL的功能.

我不确定的是设备内存,组内存和所有内存的含义.我目前的想法是

  • 组内存仅为组共享内存
  • 设备内存是GPU内存(例如纹理,缓冲区)
  • 所有内存都是设备+组共享内存

我真正不明白的是它如何映射到GLSL同步函数:

  • groupMemoryBarrier().文档说:"groupMemoryBarrier等待完成对计算着色器调用所执行的所有内存访问,相对于在同一工作组中执行其他调用的相同访问,然后返回而没有其他影响".主要问题是:

    • 尽管与HLSL中的函数具有相同的名称,但似乎这个等待所有内存事务的完成,而不仅仅是对共享内存进行分组.
  • memoryBarrier().文档说:"memoryBarrier等待使用图像变量或原子计数器导致的所有访问完成,然后返回而没有其他影响.问题是:

    • 它真的只等待完成图像和原子计数器内存事务并忽略缓冲区和共享内存吗?(memoryBarrierBuffermemoryBarrierShared建议还有其他类型的内存同步)
    • groupMemoryBarrier()memoryBarrier()shader 之间的区别是什么?我只能想象后者等待所有线程的所有事务的完成,这将产生巨大的性能影响,因此在HLSL中是不允许的.
  • memoryBarrierBuffer,memoryBarrierImagememoryBarrierAtomicCounter.文档说:"memoryBarrier*等待由于使用缓冲区/图像/原子计数器而导致的所有访问完成,然后返回而没有其他任何影响." 问题:
    • 我无法理解这是否仅与一个工作组中的线程相关,或者是否在所有工作组中的所有线程上执行同步

以下是我理解HLSL函数到GLSL的映射:

  • GroupMemoryBarrier()= groupMemoryBarrier()+memoryBarrierShared()
  • GroupMemoryBarrierWithGroupSync()= GroupMemoryBarrier()+barrier()
  • DeviceMemoryBarrier()= memoryBarrierBuffer()+ memoryBarrierImage()+memoryBarrierAtomicCounter()
  • DeviceMemoryBarrierWithGroupSync()= DeviceMemoryBarrier()+barrier()
  • AllMemoryBarrier() =所有屏障功能
  • AllMemoryBarrierWithGroupSync()= AllMemoryBarrier()+barrier()

我非常感谢帮助整理这件事.

c++ opengl

8
推荐指数
0
解决办法
1586
查看次数

MSVC 2017中STL容器的移动构造函数未标记为noexcept

我正在将我的项目从VS2015迁移到VS2017,这当然不会顺利进行。

我看到奇怪的编译器错误,可以通过以下代码重现该错误:

struct MoveOnly
{
    MoveOnly() {}
    MoveOnly(const MoveOnly&) = delete;
    MoveOnly& operator = (const MoveOnly&) = delete;
    MoveOnly(MoveOnly&&) = default;
    MoveOnly& operator = (MoveOnly&&) = default;
    bool operator == (const MoveOnly& rhs)const{return false;}
};
struct Hasher
{
    size_t operator()(const MoveOnly&)const{return 0;}
};
std::vector < std::unordered_map<MoveOnly, int, Hasher> > test;
test.emplace_back();
Run Code Online (Sandbox Code Playgroud)

我可以使用所有编译器(gcc 7.2,clang 5.0.0,icc 18以及MSVC 2015)成功编译此代码。请点击以下链接查看测试:https : //godbolt.org/g/uSqwDJ。在MSVC 2017(19.10.25017)上,但是由于编译器尝试引用MoveOnly类型已删除的副本构造函数而导致错误。对于我来说,此错误意义不大,因为没有理由在此处复制任何内容而不是移动。/std:c++14/std:c++17/std:c++latest不帮。此外,gcc和clang正确处理代码的事实使我对msvc 2017编译器感到怀疑。

更新:

之后Yakk发现的问题是什么,我想代替使用其他容器unordered_map和代码只编译vector

c++ visual-studio c++11 visual-studio-2017

5
推荐指数
1
解决办法
645
查看次数

在 CMake 中定义 Xcode 复制文件构建阶段

我的 iOS 项目使用第三方动态库,需要对其进行代码签名并捆绑到应用程序中。在 Xcode 中,这可以通过添加新的复制文件构建阶段轻松实现。Xcode 项目是使用 CMake 生成的,但是我找不到定义此复制文件构建阶段的方法。MACOSX_PACKAGE_LOCATION使库被视为捆绑资源并且不进行代码签名。

令人惊讶的是,网络上有关该主题的信息非常少,所以有人知道是否可以在 CMake 中定义复制文件构建阶段?或者,是否有另一种方法可以使用 CMake 进行代码签名和捆绑第三方动态库?

cmake

5
推荐指数
0
解决办法
414
查看次数

32 位 clang 中奇怪的结构成员包装

我偶然发现了一个非常奇怪的 struct 成员,它封装在 32 位 clang 中。这是编译器资源管理器实验的链接

本质上,我有以下结构:

struct _8Bytes
{
    uint64_t _8bytes;
};
struct _16Bytes : _8Bytes
{
    uint32_t  _4bytes;
};
struct Test : _16Bytes
{
    uint8_t test;
};
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,它sizeof(_16Bytes)是 16,但是offsetof(Test, test)它是 12,因为编译器决定在 后立即打包它_16Bytes::_4bytes。这非常烦人,我想首先禁用此行为,但就这样吧。

让我困惑的是,如果我_16Bytes按如下方式更改结构:

struct _16Bytes
{
    // Same as Test1::_16Bytes, but 8 bytes is now a member
    uint64_t _8bytes;
    uint32_t  _4bytes;
};
Run Code Online (Sandbox Code Playgroud)

然后突然offsetof(Test, test)变成了 16。这对我来说绝对是零——有人能解释一下发生了什么吗?

更重要的是,有没有办法禁用这种恼人的打包行为?

c++ clang clang++

2
推荐指数
1
解决办法
698
查看次数

标签 统计

c++ ×3

c++11 ×1

clang ×1

clang++ ×1

cmake ×1

opengl ×1

visual-studio ×1

visual-studio-2017 ×1