我听说有英特尔在线书籍描述了特定汇编指令所需的CPU周期,但我无法找到它(经过努力).有人能告诉我如何找到CPU周期吗?
下面是一个例子,在下面的代码中,mov/lock是1个CPU周期,xchg是3个CPU周期.
// This part is Platform dependent!
#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* pTargetAddress,
int nValue)
{
__asm
{
mov edx, dword ptr [pTargetAddress]
mov eax, nValue
lock xchg eax, dword ptr [edx]
}
// mov = 1 CPU cycle
// lock = 1 CPU cycle
// xchg = 3 CPU cycles
}
#endif // WIN32
Run Code Online (Sandbox Code Playgroud)
顺便说一句:这是我发布的代码的URL:http://www.codeproject.com/KB/threads/spinlocks.aspx
给定std::bitset<64> bits任意数量的位和位位置X(0-63)
在X位或更低位计数位的最有效方法是什么,如果未设置X位,则返回0
注意:如果设置该位,则返回始终至少为1
蛮力方式很慢:
int countupto(std::bitset<64> bits, int X)
{
if (!bits[X]) return 0;
int total=1;
for (int i=0; i < X; ++i)
{
total+=bits[i];
}
return total;
}
Run Code Online (Sandbox Code Playgroud)
这个count()方法bitset将为您popcount提供所有位,但bitset不支持范围
注意:这不是如何计算32位整数中的设置位数?因为它询问所有位而不是0到X的范围
我想知道各种大小的循环如何在最近的x86处理器上执行,作为uop数的函数.
以下是彼得·科德斯(Peter Cordes)的一句话,他在另一个问题中提出了非多数的问题:
我还发现,如果循环不是4 uop的倍数,则循环缓冲区中的uop带宽不是每个循环的常数4.(即它是abc,abc,......;不是abca,bcab,......).遗憾的是,Agner Fog的microarch doc对循环缓冲区的这种限制并不清楚.
问题是关于循环是否需要是N uop的倍数才能以最大uop吞吐量执行,其中N是处理器的宽度.(即最近的英特尔处理器为4).在谈论"宽度"和计算微动时,有很多复杂因素,但我大多想忽略这些因素.特别是,假设没有微观或宏观融合.
Peter给出了以下一个循环,其中包含7个uop的循环:
一个7-uop循环将发出4 | 3 | 4 | 3 | ...的组我没有测试更大的循环(不适合循环缓冲区),看看是否有可能从下一个指令开始迭代发布在与其分支相同的组中,但我不假设.
更一般地说,声称是x在其体内具有uops 的循环的每次迭代将至少进行ceil(x / 4)迭代,而不是简单地迭代x / 4.
对于部分或全部最新的x86兼容处理器,这是真的吗?
performance x86 assembly cpu-architecture micro-optimization
我希望能够手动预测任意算术的长度(即没有分支或内存,尽管这也很好)x86-64汇编代码将采用特定的体系结构,考虑到指令重新排序,超标量,延迟,消费者价格指数等
什么/描述必须遵循的规则才能实现这一目标?
我想我已经找到了一些初步规则,但是我没有找到任何关于将任何示例代码分解为这个详细程度的引用,所以我不得不做一些猜测.(例如,英特尔优化手册甚至几乎没有提到指令重新排序.)
至少,我正在寻找(1)确认每条规则是正确的,或者是每条规则的正确陈述,以及(2)我可能忘记的任何规则的列表.
addps并且subps使用相同的功能) unit?我如何确定?).和:4此循环已经发出少于超标量宽度(通常)指令的数量.例如,请考虑以下示例代码(计算交叉产品):
shufps xmm3, xmm2, 210
shufps xmm0, xmm1, 201
shufps xmm2, xmm2, 201
mulps xmm0, xmm3
shufps xmm1, xmm1, 210
mulps xmm1, xmm2
subps xmm0, xmm1
Run Code Online (Sandbox Code Playgroud)
我试图预测Haswell的延迟看起来像这样:
; `mulps` Haswell latency=5, CPI=0.5
; `shufps` Haswell latency=1, CPI=1
; `subps` Haswell latency=3, CPI=1
shufps xmm3, xmm2, 210 ; cycle 1
shufps xmm0, xmm1, 201 ; cycle 2
shufps xmm2, xmm2, 201 ; …Run Code Online (Sandbox Code Playgroud) 编辑:正如 Cody Gray 在他的评论中指出的那样,禁用优化的分析完全是浪费时间。那么我应该如何进行这个测试呢?
微软在其XMVectorZero情况下定义了_XM_SSE_INTRINSICS_使用_mm_setzero_ps和{0.0f,0.0f,0.0f,0.0f}不使用。我决定看看胜利有多大。因此,我在 Release x86 中使用了以下程序,并将配置属性>C/C++>优化>优化设置为Disabled (/Od)。
constexpr __int64 loops = 1e9;
inline void fooSSE() {
for (__int64 i = 0; i < loops; ++i) {
XMVECTOR zero1 = _mm_setzero_ps();
//XMVECTOR zero2 = _mm_setzero_ps();
//XMVECTOR zero3 = _mm_setzero_ps();
//XMVECTOR zero4 = _mm_setzero_ps();
}
}
inline void fooNoIntrinsic() {
for (__int64 i = 0; i < loops; ++i) {
XMVECTOR zero1 = { 0.f,0.f,0.f,0.f };
//XMVECTOR zero2 …Run Code Online (Sandbox Code Playgroud) 英特尔内在函数指南列出的吞吐量是每个线程还是每个核心?
我的教科书(计算机系统:程序员的观点)指出,当一系列操作必须严格按顺序执行时,就会遇到延迟界限,而吞吐量界限则表征处理器功能单元的原始计算能力。
课本5.5、5.6题介绍了这两种可能的多项式计算循环结构
double result = a[0];
double xpwr = x;
for (int i = 1; i <= degree; i++) {
result += a[i] * xpwr;
xpwr = x * xpwr;
}
Run Code Online (Sandbox Code Playgroud)
和
double result = a[degree];
double xpwr = x;
for (int i = degree - 1; i >= 0; i--) {
result = a[i] + x * result;
}
Run Code Online (Sandbox Code Playgroud)
假设循环在具有以下执行单元的微体系结构上执行:
为这个问题给出的浮点乘法和加法的延迟界限分别是 5.0 和 3.0。根据答案键,第一个循环的总循环延迟是每个元素 5.0 个周期,第二个是每个元素 8.0 个周期。我不明白为什么第一个循环不是 8.0。
似乎 a[i] …
assembly ×4
performance ×3
c++ ×2
sse ×2
x86 ×2
algorithm ×1
cpu ×1
cycle ×1
intrinsics ×1
latency ×1
pipeline ×1
profiling ×1
simd ×1
superscalar ×1
x86-64 ×1