相关疑难解决方法(0)

C循环优化有助于最终分配

因此,对于我在计算机系统课程中的最终作业,我们需要优化这些forloops,使其比原始版本更快.使用我们的linux服务器,基本等级不到7秒,完整等级不到5秒.我在这里的代码大约需要5.6秒.我想我可能需要以某种方式使用指针来使它更快,但我不是很确定.任何人都可以提供我的任何提示或选项吗?非常感谢!

QUICKEDIT:文件必须保持50行或更少,我忽略了教师所包含的那些注释行.

#include <stdio.h>
#include <stdlib.h>

// You are only allowed to make changes to this code as specified by the comments in it.

// The code you submit must have these two values.
#define N_TIMES     600000
#define ARRAY_SIZE   10000

int main(void)
{
    double  *array = calloc(ARRAY_SIZE, sizeof(double));
    double  sum = 0;
    int     i;

    // You can add variables between this comment ...
    register double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, …
Run Code Online (Sandbox Code Playgroud)

c optimization loops compiler-optimization debug-mode

8
推荐指数
2
解决办法
5650
查看次数

在预测现代超标量处理器上的操作延迟时需要考虑哪些因素以及如何手动计算它们?

我希望能够手动预测任意算术的长度(即没有分支或内存,尽管这也很好)x86-64汇编代码将采用特定的体系结构,考虑到指令重新排序,超标量,延迟,消费者价格指数等

什么/描述必须遵循的规则才能实现这一目标?


我想我已经找到了一些初步规则,但是我没有找到任何关于将任何示例代码分解为这个详细程度的引用,所以我不得不做一些猜测.(例如,英特尔优化手册甚至几乎没有提到指令重新排序.)

至少,我正在寻找(1)确认每条规则是正确的,或者是每条规则的正确陈述,以及(2)我可能忘记的任何规则的列表.

  • 每个循环发出尽可能多的指令,从当前循环开始按顺序开始,并且可能与重新排序缓冲区大小一样远.
  • 如果出现以下情况,可以在给定周期发出指令:
    • 没有影响其操作数的指令仍在执行中.和:
    • 如果它是浮点指令,则它之前的每个浮点指令都被发出(浮点指令具有静态指令重新排序).和:
    • 该循环有一个功能单元可用于该指令.每个(?)功能单元是流水线的,这意味着它可以在每个周期接受1个新指令,并且对于给定功能类的CPI,总功能单元的数量是1/CPI(这里模糊不清:可能是例如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)

assembly pipeline latency x86-64 superscalar

8
推荐指数
1
解决办法
268
查看次数

Unix命令用于基准测试代码运行K次

假设我有一个在Unix中执行的代码:

$ ./mycode
Run Code Online (Sandbox Code Playgroud)

我的问题是有没有办法让我的代码运行时间达到K次.例如,K = 1000的值.

我知道Unix"time"命令,但是只执行了1个实例.

c++ unix performance benchmarking

7
推荐指数
3
解决办法
2015
查看次数

为什么使用 AVX-512 指令转换数组时,与 7 或 9 个批次相比,以 8 个批次进行转换时要慢得多?

请考虑以下最小示例minimal.cpphttps://godbolt.org/z/x7dYes91M)。

#include <immintrin.h>

#include <algorithm>
#include <ctime>
#include <iostream>
#include <numeric>
#include <vector>

#define NUMBER_OF_TUPLES 134'217'728UL

void transform(std::vector<int64_t>* input, std::vector<double>* output, size_t batch_size) {
  for (size_t startOfBatch = 0; startOfBatch < NUMBER_OF_TUPLES; startOfBatch += batch_size) {
    size_t endOfBatch = std::min(startOfBatch + batch_size, NUMBER_OF_TUPLES);

    for (size_t idx = startOfBatch; idx < endOfBatch;) {
      if (endOfBatch - idx >= 8) {
        auto _loaded = _mm512_loadu_epi64(&(*input)[idx]);
        auto _converted = _mm512_cvtepu64_pd(_loaded);

        _mm512_storeu_epi64(&(*output)[idx], _converted);
        idx += 8;
      } else {
        (*output)[idx] …
Run Code Online (Sandbox Code Playgroud)

c++ performance benchmarking clang avx512

7
推荐指数
1
解决办法
938
查看次数

为什么strtolower比strtoupper略慢?

我出于好奇做了一个实验.我想看看是否有在所有之间的差异微strtolower()strtoupper().我预计strtolower()大多数小写字符串会更快,反之亦然.我发现这种strtolower()情况在所有情况下都比较慢(尽管在你完成数百万次之前完全无关紧要.)这是我的考验.

$string = 'hello world';
$start_time = microtime();
for ($i = 0; $i < 10000000; $i++) {
    strtolower($string);
}
$timed = microtime() - $start_time;
echo 'strtolower ' . $string . ' - ' . $timed . '<br>';
Run Code Online (Sandbox Code Playgroud)

重复strtolower()strtoupper()使用hello world,HELLO WORLD以及Hello World.这是完整的要点.我已经多次运行代码并继续获得大致相同的结果.这是下面的一次测试.

strtolower hello world - 0.043829
strtoupper hello world - 0.04062
strtolower HELLO WORLD - 0.042691
strtoupper HELLO WORLD - …
Run Code Online (Sandbox Code Playgroud)

php c performance micro-optimization

6
推荐指数
1
解决办法
867
查看次数

使用空构造函数会使数组未初始化,从而导致计算速度变慢

我对一件事感到非常困惑...如果我将构造函数添加到 struct A 中,那么 for 循环中的计算会变得慢很多倍。为什么?我不知道。

在我的计算机上,输出中的代码片段的时间为:

有构造函数:1351

没有构造函数:220

这是一个代码:

#include <iostream>
#include <chrono>
#include <cmath>

using namespace std;
using namespace std::chrono;

const int SIZE = 1024 * 1024 * 32;

using type = int;

struct A {
    type a1[SIZE];
    type a2[SIZE];
    type a3[SIZE];
    type a4[SIZE];
    type a5[SIZE];
    type a6[SIZE];

    A() {} // comment this line and iteration will be twice faster
};

int main() {
    A* a = new A();
    int r;
    high_resolution_clock::time_point t1 = high_resolution_clock::now();
    for (int i …
Run Code Online (Sandbox Code Playgroud)

c++ optimization default-constructor compiler-optimization visual-studio-2013

6
推荐指数
1
解决办法
273
查看次数

为什么 static_cast 转换会加速整数除法函数的未优化构建?

...或者更确切地说,为什么static_cast-ing不会减慢我的功能?

考虑下面的函数,它执行整数除法:

int Divide(int x, int y) {
  int ret = 0, i = 32;
  long j = static_cast<long>(y) << i;
  while (x >= y) {
    while (x < j) --i, j >>= 1;
    ret += 1 << i, x -= j;
  }
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

正如人们所期望的那样,这表现得相当不错。但是,如果我们删除static_cast第 3 行,如下所示:

int Divide(int x, int y) {
  int ret = 0, i = 32;
  long j = y << i;
  while (x >= y) {
    while (x < …
Run Code Online (Sandbox Code Playgroud)

c++ assembly x86-64 type-conversion undefined-behavior

6
推荐指数
1
解决办法
333
查看次数

简单的()循环基准测试与任何循环绑定需要相同的时间

我愿意编写一个代码,让我的CPU执行一些操作,看看他花了多少时间来解决它们.我想做一个从i = 0到i <5000的循环,然后将i乘以一个常数和时间.我最终得到了这个代码,它没有错误,但即使我更改循环i <49058349083或者如果i <2它需要相同的时间,它只需要0.024秒来执行代码.是什么错误?

PD:我昨天开始学习C++我很抱歉,如果这是一个非常容易回答的问题,但我找不到解决方案

#include <iostream>
#include <ctime>

using namespace std;

int main () {
    int start_s=clock();

    int i;
    for(i=0;i<5000;i++){
        i*434243;
    }

    int stop_s=clock();
    cout << "time: "<< (stop_s-start_s)/double(CLOCKS_PER_SEC)*1000;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ performance benchmarking microbenchmark

5
推荐指数
2
解决办法
568
查看次数

使用 SIMD (System.Numerics) 编写向量和函数并使其比 for 循环更快

double[]我编写了一个函数来使用 SIMD 将数组的所有元素相加(System.Numerics.Vector,性能比 na\xc3\xafve 方法差。

\n

在我的电脑上Vector<double>.Count是 4,这意味着我可以创建一个包含 4 个值的累加器,并运行数组,按组将元素相加。

\n

例如,一个 10 元素数组,带有 4 元素累加器和 2 个剩余元素,我会得到

\n
//     | loop                  | remainder\nacc[0] = vector[0] + vector[4] + vector[8]\nacc[1] = vector[1] + vector[5] + vector[9]\nacc[2] = vector[2] + vector[6] \nacc[3] = vector[3] + vector[7] \n
Run Code Online (Sandbox Code Playgroud)\n

和结果sum = acc[0]+acc[1]+acc[2]+acc[3]

\n

下面的代码产生了正确的结果,但与仅将值相加的循环相比,速度不高

\n
public static double SumSimd(this Span<double> a)\n{\n    var n = System.Numerics.Vector<double>.Count;\n    var count = a.Length;\n    // divide array into n=4 element groups\n …
Run Code Online (Sandbox Code Playgroud)

c# arrays performance simd avx

5
推荐指数
2
解决办法
2734
查看次数

故意提高 L1 缓存未命中率的程序

我目前正在尝试编写一个 L1 缺失率尽可能高的程序。

为了测量 L1 缺失率,我在 Intel Core i7 处理器上使用 MEM_LOAD_RETIRED.L1_MISS 和 MEM_LOAD_RETIRED.L1_HIT 性能计数器事件(我对填充缓冲区命中不感兴趣)。我修改了 Linux 内核,以便在每次上下文切换时提供准确的测量结果,以便我可以准确地确定每个程序的命中和未命中次数。

硬件预取器被禁用

这是我目前拥有的代码:

#define LINE_SIZE 64
#define CACHE_SIZE 4096 * 8
#define MEM_SIZE CACHE_SIZE * 64


void main(int argc, char* argv[])
{

    volatile register char* addr asm ("r12") = mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);

    volatile register unsigned long idx asm ("r13") = 0;
    volatile register unsigned long store_val asm ("r14") = 0;

    volatile register unsigned long x64 asm ("r15") = 88172645463325252ull;

    while(1) …
Run Code Online (Sandbox Code Playgroud)

c linux intel cpu-cache

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