设置,读取,移动和比较等操作是否需要同时执行?
如果没有:有没有办法找出多久.
我的意思是什么名称,某些特定类型cpu执行不同汇编语言指令的速度(移动,读取等)
我有两段 C++ 代码,它们执行相同的计算。与代码 A 相比,代码 B 确实减少了大约 33% 的指令,大约减少了 17% 的内存访问,但运行速度是代码 A 的四倍(而不是两倍)。会是什么原因呢?此外,我们如何才能确认您的回答所提供的主张?
在这两个代码中,
howmany是 20 000 000testees有 20 000 000 个元素,mt19937在启动时(在这些片段之前)为代码 A 和代码 B 随机生成 ( )。-O1代码 A - 运行时间约为。95 至 110 毫秒
GF2 sum {GF2(1)};
auto a = system_clock::now();
for(size_t i=0;i<howmany;i++){
sum *= testees[i];
}
auto b = system_clock::now();
Run Code Online (Sandbox Code Playgroud)
代码 B - 运行时间约为。25 至 30 毫秒
GF2 sum1 {GF2(1)};
GF2 sum2 {GF2(1)};
GF2 sum3 …Run Code Online (Sandbox Code Playgroud) 我正在做一个家庭作业问题,要求我找出运行我在C中写的短程序时执行的机器代码指令的数量.
问题是我可以使用我想要的任何工具来解决它,但我对C很新,并且很少知道如何解决这个问题.
我需要哪些类型的工具来解决这个问题?
我使用 C++ 对多个 NOP 指令和单个 NOP 指令进行计时rdtsc。但是,我没有发现执行 NOP 所需的周期数与执行的 NOP 数成正比。我很困惑为什么会出现这种情况。我的 CPU 是 Intel Core i7-5600U @ 2.60Ghz。
这是代码:
#include <stdio.h>
int main() {
unsigned long long t;
t = __rdtsc();
asm volatile("nop");
t = __rdtsc() - t;
printf("rdtsc for one NOP: %llu\n", t);
t = __rdtsc();
asm volatile("nop; nop; nop; nop; nop; nop; nop;");
t = __rdtsc() - t;
printf("rdtsc for seven NOPs: %llu\n", t);
}
Run Code Online (Sandbox Code Playgroud)
我得到的值如下:
rdtsc for one NOP: 78
rdtsc for seven NOPs: 91 …Run Code Online (Sandbox Code Playgroud) 我试图了解全局静态变量的性能,并遇到了一个非常奇怪的场景。下面的代码平均需要大约 525 毫秒。
static unsigned long long s_Data = 1;
int main()
{
unsigned long long x = 0;
for (int i = 0; i < 1'000'000'000; i++)
{
x += i + s_Data;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
下面的代码平均需要 1050 毫秒。
static unsigned long long s_Data = 1;
int main()
{
unsigned long long x = 0;
for (int i = 0; i < 1'000'000'000; i++)
{
x += i;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道访问静态变量很快,根据我的其他测试,写入它们很慢,但我不确定在上述场景中我错过了哪些信息。注意:编译器优化已关闭,并使用 MSVC 编译器来执行测试。
我认为我对延迟和吞吐量之间的差异有一个很好的理解.但是,对于Intel Intrinsics来说,延迟对指令吞吐量的影响并不清楚,特别是在顺序(或几乎顺序)使用多个内部调用时.
例如,让我们考虑一下:
_mm_cmpestrc
Run Code Online (Sandbox Code Playgroud)
它的延迟为11,Haswell处理器的吞吐量为7.如果我在一个循环中运行这个指令,那么在11个循环后我会得到一个连续的每循环输出吗?由于这需要一次运行11条指令,并且因为我的吞吐量为7,所以我是否会用完"执行单元"?
我不确定如何使用延迟和吞吐量,除了得到一条指令相对于不同版本的代码需要多长时间的印象.
我看到这个非常有趣的推文:
抵制我的代码高尔夫本能
if(!bool1 && bool2)变成if(bool1<bool2)
我之前从未见过,所以我想看看编译器是否也会使用这种优化.我开始使用自述文件和测试C程序进行回购:https://github.com/ndbroadbent/gcc_experiments
这是测试程序:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int main(int argc, const char* argv[]) {
if(argc != 3) {
printf("Usage: %s <a> <b>\n", argv[0]);
exit(1);
}
bool a = strtol(argv[1], NULL, 10) != 0;
bool b = strtol(argv[2], NULL, 10) != 0;
if (!a && b) {
printf("!a && b == true (a: %d, b: %d)\n", a, b);
} else {
printf("!a && b == false (a: %d, …Run Code Online (Sandbox Code Playgroud) vpcmpeqd xmm15, xmm15, xmm15
vpor xmm0, xmm0, xmm1
vpandn xmm0, xmm0, xmm15
Run Code Online (Sandbox Code Playgroud) 在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用?
例如:我想使用vgatherdps消耗两个 ymm 寄存器的指令,其中之一是位移索引。我意识到vgatherdps收集数据需要花费大量时间,因为数据的局部性较差。
位移索引寄存器是否会在指令执行期间被保留,或者我可以在后续指令中重用它而无需挂起管道?
我想知道为什么像这样的简单循环无法达到我的 CPU 时钟速度(4,2Ghz):
float sum = 0;
for (int i = 0; i < 1000000; i+=1) {
sum = sum * 1 + 1;
}
Run Code Online (Sandbox Code Playgroud)
凭直觉,我希望在不到 1 毫秒(例如 0,238 毫秒)的时间内实现这一目标,每秒进行 42 亿次迭代。但我得到的时间约为 3 毫秒,即每秒约 3.33 亿次迭代。
我假设做数学运算需要 2 个周期,一个用于乘法,另一个用于求和。假设我正在执行 6.66 亿次操作……看起来仍然很慢。然后我假设循环比较需要一个周期,循环计数器需要另一个周期......
所以我创建了以下代码来删除循环......
void listOfSums() {
float internalSum = 0;
internalSum = internalSum * 1 + 1;
internalSum = internalSum * 1 + 1;
internalSum = internalSum * 1 + 1;
internalSum = internalSum * 1 + 1;
// Repeated 100k …Run Code Online (Sandbox Code Playgroud)