我使用llvm-mca来计算一堆代码的总周期,认为它们会预测它的运行时间.但是,动态测量运行时几乎没有相关性.那么:为什么由llvm-mca计算的总周期不能准确预测运行时?我可以用llvm-mca以更好的方式预测运行时吗?
细节:
我想知道,对于不同类型的下面的代码的运行时间begin(和end)迭代器,对startValue正在0.0或0ULL:
std::accumulate(begin, end, starValue)
Run Code Online (Sandbox Code Playgroud)
为了预测运行时,我使用Compiler Explorer(https://godbolt.org/z/5HDzSF)及其LLVM机器码分析器(llvm-mca)插件,因为llvm-mca是"一个使用可用信息的性能分析工具"在LLVM(例如调度模型)中静态测量性能".我使用了以下代码:
using vec_t = std::vector<double>;
vec_t generateRandomVector(vec_t::size_type size)
{
std::random_device rnd_device;
std::mt19937 mersenne_engine {rnd_device()};
std::uniform_real_distribution dist{0.0,1.1};
auto gen = [&dist, &mersenne_engine](){
return dist(mersenne_engine);
};
vec_t result(size);
std::generate(result.begin(), result.end(), gen);
return result;
}
double start()
{
vec_t vec = generateRandomVector(30000000);
vec_t::iterator vectorBegin = vec.begin();
vec_t::iterator vectorEnd = vec.end();
__asm volatile("# LLVM-MCA-BEGIN stopwatchedAccumulate");
double result = std::accumulate(vectorBegin, vectorEnd, 0.0);
__asm …Run Code Online (Sandbox Code Playgroud) 我想实现一些快速的凸分析操作 - 近端运算符等。我是 Cython 的新手,认为这将是完成这项工作的正确工具。mwe_py.py我在纯 Python 和 Cython (及以下)中都有实现mwe_c.pyx。然而,当我比较它们时,Python + Numpy 版本明显快于 Cython 版本。为什么是这样?我尝试过使用内存视图,它应该允许更快的索引/操作;但是,性能差异非常明显!任何有关如何修复mwe_c.pyx以下问题以接近“最佳”Cython 代码的建议将不胜感激。
import pyximport; pyximport.install(language_level=3)
import mwe_c
import mwe_py
import numpy as np
from time import time
n = 100000
nreps = 10000
x = np.random.randn(n)
z = np.random.randn(n)
tau = 1.0
t0 = time()
for _ in range(nreps):
out = mwe_c.prox_translation(mwe_c.prox_two_norm, x, z, tau)
t1 = time()
print(t1 - t0)
t0 = time()
for _ in range(nreps):
out = mwe_py.prox_translation(mwe_py.prox_two_norm, …Run Code Online (Sandbox Code Playgroud) C++ 编译器选项-ffast-math允许编译器执行更多数学优化,这可能会稍微改变行为。例如,x * 10 / 10应该取消,但由于溢出的可能性,它会稍微改变行为,并且x / 10.0 / 10.0可能具有与 不同的舍入误差x / 100.0。
然而,正如许多资源所指出的那样,包括 StackOverflow 上的许多问题,-ffast-mathC++ 编译器选项可能会导致跨平台的奇怪行为。相反,推荐的方法是在您希望编译器优化的操作周围手动添加括号。
有没有办法识别代码库的这些部分?某种静态分析工具可以找到-ffast-math启用后会有所不同的所有代码行,以便程序员即使在未启用的情况下也可以手动调整要优化的代码行-ffast-math?
我有以下循环来计算 C++ 中的基本汇总统计数据(平均值、标准差、最小值和最大值),跳过缺失值(x 是双向量):
int k = 0;
long double sum = 0.0, sq_sum = 0.0;
double minv = 1.0/0.0, maxv = -1.0/0.0;
#pragma omp simd reduction(+:sum,sq_sum,k) reduction(max:maxv) reduction(min:minv)
for (int i = 0; i < n; ++i) {
double xi = x[i];
int tmp = xi == xi;
sum += tmp ? xi : 0.0;
sq_sum += tmp ? xi * xi : 0.0;
k += tmp ? 1 : 0;
minv = minv > xi ? xi : …Run Code Online (Sandbox Code Playgroud) 在编译我的代码时使用这个选项获得了巨大的加速。从手册页它说这个选项:
在调用使用单条指令执行的数学函数后不要设置“errno”,例如“sqrt”
我不清楚“errno”是什么,以及它是如何在其他地方使用的(这与程序的退出代码相同吗?)此外,手册页说:
依赖 IEEE 异常进行数学错误处理的程序可能希望使用此标志来提高速度,同时保持 IEEE 算术兼容性。
我不清楚这意味着什么,是 c++ 的 IEEE 例外标准或 c++ 的公共库(例如 Eigen、Boost 等)
本质上,我试图确定这是否是在我的代码中使用的“安全”选项,或者我应该从使用中了解哪些副作用。一个以前的回答说,这可能会影响“线程局部变量”,但我不知道这意味着什么。
编辑:我的代码是一个简单的一次性程序代码,用于处理科学问题。它不会成为需要复杂错误处理的深度嵌入系统的一部分。但是,代码不能以微妙、无声的方式失败。
我是C ++的初学者,已经被赋予编写计算数字幂的函数的任务,但是我们不允许使用pow函数或循环。
函数的用户必须在命令窗口中输入基数和指数。
什么是开始的好地方?
我正在尝试编写一个与numpy.sum双精度数组一样快的 C 程序,但似乎失败了。
以下是我衡量 numpy 性能的方法:
import numpy as np
import time
SIZE=4000000
REPS=5
xs = np.random.rand(SIZE)
print(xs.dtype)
for _ in range(REPS):
start = time.perf_counter()
r = np.sum(xs)
end = time.perf_counter()
print(f"{SIZE / (end-start) / 10**6:.2f} MFLOPS ({r:.2f})")
Run Code Online (Sandbox Code Playgroud)
输出是:
float64
2941.61 MFLOPS (2000279.78)
3083.56 MFLOPS (2000279.78)
3406.18 MFLOPS (2000279.78)
3712.33 MFLOPS (2000279.78)
3661.15 MFLOPS (2000279.78)
Run Code Online (Sandbox Code Playgroud)
现在尝试在 C 中做类似的事情:
float64
2941.61 MFLOPS (2000279.78)
3083.56 MFLOPS (2000279.78)
3406.18 MFLOPS (2000279.78)
3712.33 MFLOPS (2000279.78)
3661.15 MFLOPS (2000279.78)
Run Code Online (Sandbox Code Playgroud)
编译并gcc -o main …
我刚刚了解到,C 中的加法运算比乘法运算更快。因此,我很好奇(a+b)*c计算速度是否会比 C 更快a*c+b*c?
我遇到了一个错误,我的无穷大变量不等于无穷大。我什至不确定在哪种情况下。
这是最小的例子:
#include <iostream>
#include <limits>
#include <cmath>
using namespace std;
constexpr auto NT_INF = std::numeric_limits<double>::infinity();
// prints a number byte-by-byte
void printN(double n){
auto tmp = (uint8_t*)&n;
for (int i = 0; i < 8; i++) {
wprintf(L"%4d ", tmp[i]);
}
wprintf(L"\n");
};
double * genNumbers() {
double * numbers = new double[6];
numbers[0] = 100;
numbers[1] = 1;
numbers[2] = 198263783302;
numbers[3] = 198263783302;
numbers[4] = 100;
numbers[5] = 0;
return numbers;
}
int main()
{
// leave …Run Code Online (Sandbox Code Playgroud) 我有以下代码,它接受输入 anx并填充输出向量y,我想使用 OpenMPsimd指令对其进行向量化:
for (size_t qi = 0; qi < nq; ++qi){
const auto ii = face_indices[qi*3], jj = face_indices[qi*3+1], kk = face_indices[qi*3+2];
y[ii] += x[kk] * fpl[ii] * fq[qi] * fpr[kk] - x[jj] * fpl[ii] * fq[qi] * fpr[jj];
y[kk] += x[ii] * fpl[kk] * fq[qi] * fpr[ii] - x[jj] * fpl[kk] * fq[qi] * fpr[jj];
y[jj] -= x[ii] * fpl[jj] * fq[qi] * fpr[ii] + x[kk] * fpl[jj] * fq[qi] * fpr[kk]; …Run Code Online (Sandbox Code Playgroud) 任何人都可以帮助我理解使用gcc编译时-ffast-math选项的作用.使用-O3和-ffast-math执行时,我看到程序执行时间相差20秒,而只使用-O3