这两个代码片段做同样的事情:将两个float数组一起添加并将结果存储回它们.
内联汇编程序:
void vecAdd_SSE(float* v1, float* v2) {
_asm {
mov esi, v1
mov edi, v2
movups xmm0, [esi]
movups xmm1, [edi]
addps xmm0, xmm1
movups [esi], xmm0
movups [edi], xmm0
}
}
Run Code Online (Sandbox Code Playgroud)
普通C++代码:
void vecAdd_Std(float* v1, float* v2) {
v1[0] = v1[0]+ v2[0];
v1[1] = v1[1]+ v2[1];
v1[2] = v1[2]+ v2[2];
v1[3] = v1[3]+ v2[3];
v2[0] = v1[0];
v2[1] = v1[1];
v2[2] = v1[2];
v2[3] = v1[3];
}
Run Code Online (Sandbox Code Playgroud)
C++代码的反汇编(在调试模式下进行反汇编,因为由于某种原因我无法在发布模式下查看反汇编):
void vecAdd_Std(float* v1, float* v2) {
push ebp
mov ebp,esp …Run Code Online (Sandbox Code Playgroud) 有人可以解释英特尔内部指南中给出的延迟和吞吐量值吗?
我是否正确理解延迟是指令运行所需的时间单位,吞吐量是每个时间单位可以启动的指令数量?
如果我的定义是正确的,为什么某些指令的延迟在较新的CPU版本上更高(例如mulps)?
我在我的字符串类中重载了一个函数,然而,它永远不会被调用.为什么?
template <class T>
class StringT {
public:
void assign(const T* ptr);
template <size_t N> void assign(const T(&ptr)[N]);
};
int main() {
StringT<char> str;
str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12])
}
Run Code Online (Sandbox Code Playgroud) 我想知道在编译时是否可以计算基类偏移量。当然,在运行时很容易做到,因为static_cast可以利用的功能,并且偏移量只是指向派生类的指针的基指针之间的差异。
我在编译时第一次尝试得到它看起来像下面这样:
struct InterfaceRoot {};
struct IInterface1 : InterfaceRoot {
virtual void MethodI1() = 0;
};
struct IInterface2 : InterfaceRoot {
virtual void MethodI2() = 0;
};
class CClass : public IInterface1, public IInterface2 {
virtual void MethodI1() override { /* do something */ }
virtual void MethodI2() override { /* do something */ }
};
int main() {
CClass instance;
constexpr int offsetI1 = 0; //first base class has no offset
constexpr int offsetI2 = sizeof(IInterface1);
//check …Run Code Online (Sandbox Code Playgroud) 我刚刚开始学习新的 DirectX 12 API。我想在 dx12 之上编写一种渲染引擎,并且在初始化期间我应该创建描述符堆。问题在于,此时我不知道我将来会创建多少资源视图。例如,如果我想包含一些需要渲染到纹理方法的后期处理效果,我必须为我渲染的纹理创建渲染目标视图。不过,这些 RTV 的数量可能会有所不同。那么如何创建足够大的描述符堆以应对各种情况呢?
有什么建议吗?
请考虑以下情形:有一个类CDriver负责枚举所有连接的输出设备(由COutput类表示).代码可能如下所示:
class COutput
{
// COutput stuff
};
class CDriver
{
public:
CDriver(); // enumerate outputs and store in m_outputs
// some other methods
private:
std::vector<COutput> m_outputs;
};
Run Code Online (Sandbox Code Playgroud)
现在CDriver应该能够授予用户访问枚举COutput的权限.
实现此目的的第一种方法是返回一个指针:
const COutput* GetOutput(unsigned int idx) const
{
return idx < m_outputs.size() ? &m_outputs[idx] : nullptr;
}
Run Code Online (Sandbox Code Playgroud)
我看到它的方式,这个方法提出的问题是,如果指针由用户存储并且在CDriver对象被销毁后它仍然存在,那么它现在是一个悬空指针.这是因为在对象COutput的析构函数中,指针对象(对象)已被破坏CDriver.
第二种方式是通过引用返回:
const COutput& GetOutput(unsigned int idx) const
{
return idx < m_outputs.size() ? &m_outputs[idx] : m_invalidOutput;
}
Run Code Online (Sandbox Code Playgroud)
这里同样的问题适用于带指针的方法.此外,还有一个警告,即不能返回真正的无效对象.如果a nullptr …
我有一个单例实现,但我不确定它包含哪些缺点。有人能告诉我这个实施有多好吗?
template <class Child>
class Singleton {
public:
inline static Child& Instance() {
return Instance_;
}
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
protected:
Singleton() = default;
private:
static Child Instance_;
};
template <typename Child> Child Singleton<Child>::Instance_;
Run Code Online (Sandbox Code Playgroud)
我知道 Scott Meyers 的 Singleton 实现定义了函数Instance_内部的静态GetInstance()。
inline static Child& Instance() {
static Child Instance_;
return Instance_;
}
Run Code Online (Sandbox Code Playgroud)
但这是否会带来额外的开销,因为每次调用该函数时都必须检查该函数是否Instance_已初始化。
是它更快地通过的装置计算两个向量的点积dpps指令形式SSE 4.1指令集或通过使用一系列的addps,shufps并mulps从SSE 1?
c++ ×6
performance ×4
assembly ×2
x86 ×2
directx ×1
directx-12 ×1
intel ×1
intrinsics ×1
optimization ×1
overloading ×1
pointers ×1
reference ×1
simd ×1
sse ×1
templates ×1