我是 SSE 内在函数的新手,并尝试通过它来优化我的代码。这是我的程序,用于计算等于给定值的数组元素。
我将代码更改为 SSE 版本,但速度几乎没有改变。我想知道我是否以错误的方式使用SSE......
此代码用于不允许我们启用编译器优化选项的分配。
无 SSE 版本:
int get_freq(const float* matrix, float value) {
int freq = 0;
for (ssize_t i = start; i < end; i++) {
if (fabsf(matrix[i] - value) <= FLT_EPSILON) {
freq++;
}
}
return freq;
}
Run Code Online (Sandbox Code Playgroud)
上交所版本:
#include <immintrin.h>
#include <math.h>
#include <float.h>
#define GETLOAD(n) __m128 load##n = _mm_load_ps(&matrix[i + 4 * n])
#define GETEQU(n) __m128 check##n = _mm_and_ps(_mm_cmpeq_ps(load##n, value), and_value)
#define GETCOUNT(n) count = _mm_add_ps(count, check##n)
int get_freq(const float* matrix, float …Run Code Online (Sandbox Code Playgroud) 我的问题是关于时间优化。通过执行以下操作,for 循环是否更快:
std::vector<int> myVec = {0,1,2,3};
for(int i = 0; i < myVec.size(); i++){}
Run Code Online (Sandbox Code Playgroud)
或者最好的做法是预先计算大小?
std::vector<int> myVec = {0,1,2,3};
int myVecSize = myVec.size();
for(int i = 0; i < myVecSize ; i++){}
Run Code Online (Sandbox Code Playgroud)
我在这里不仅想知道纯粹的时间执行,还想知道它是否会导致以某种方式出现一些问题
让我们看一下这个例子:
String var;
while (...) {
var = ...
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
在本例中,我们创建对对象的引用String,并在循环的每次迭代中为其分配不同的对象。
现在,在另一个例子中:
while (...) {
String var = ...
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
如果我们假设编译器很幼稚,它只会在每次迭代时String分配对堆栈上对象的引用。
或者会吗?这就是我的问题 - (a?) Java 编译器是否执行此优化?我总是将对象声明保留在尽可能广泛的范围内,因为我担心这一点,但如果编译器已经这样做了,那么我的鞋子上就少了一颗鹅卵石。
先感谢您!
我有以下 C 函数:
void proc(long a1, long *a1p,
int a2, int *a2p,
short a3, short *a3p,
char a4, char *a4p)
{
*a1p += a1;
*a2p += a2;
*a3p += a3;
*a4p += a4;
}
Run Code Online (Sandbox Code Playgroud)
使用Godbolt,我已将其转换为 x86_64 程序集(为简单起见,我使用该-Og标志来最小化优化)。它产生以下组件:
proc:
movq 16(%rsp), %rax
addq %rdi, (%rsi)
addl %edx, (%rcx)
addw %r8w, (%r9)
movl 8(%rsp), %edx
addb %dl, (%rax)
ret
Run Code Online (Sandbox Code Playgroud)
我对汇编的第一行感到困惑:movq 16(%rsp), %rax. 我知道%rax寄存器用于存储返回值。但是该proc过程没有返回值。所以我很好奇为什么在此处使用该寄存器,而不是 %r9其他一些不用于返回值的寄存器。
相对于其他指令,我也对这条指令的位置感到困惑。它首先出现,远在%rax任何需要其目标寄存器之前(实际上,直到最后一步才需要该寄存器)。它也出现在 之前addq %rdi, (%rsi) …
测试代码:
#include <array>
int test(const std::array<int, 10> &arr) {
return arr[9];
}
Run Code Online (Sandbox Code Playgroud)
我要实现arr[0]像C风格数组一样高效,这意味着内联STL数组[]运算符函数。
我检查了生成汇编代码:
$ g++ --std=c++17 -c test.cpp && objdump -d -C test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <test(std::array<int, 10ul> const&)>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 7d f8 mov %rdi,0xfffffffffffffff8(%rbp)
c: 48 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%rax
10: be 09 00 00 00 mov $0x9,%esi
15: 48 89 …Run Code Online (Sandbox Code Playgroud) 我遇到了一些速度很快的优化代码,但它使我的代码变得丑陋。
一个最小的例子如下:
enum class Foo : char {
A = 'A',
B = 'B'
};
struct A_t {
constexpr operator Foo() const { return Foo::A; }
};
void function_v1(Foo s){
if(s == Foo::A){
//Run special version of the code
} else {
//Run other version of the code
}
}
template<class foo_t>
void function_v2(foo_t s){
if(s == Foo::A){
//Run special version of the code
} else {
//Run other version of the code
}
}
int main(){
// Version 1 …Run Code Online (Sandbox Code Playgroud) 如果运行Python代码然后调用exit(),它将退出程序并且以下代码将不会运行。但是我添加exit()到我的程序中,然后出现一些语法错误并且程序崩溃了。我想知道为什么 Python 编译器在运行之前没有优化我的代码。我用逻辑错误尝试了这个问题,但它忽略了它们,比如index out of range等等。那么为什么下面的代码不起作用并SyntaxError发生呢?
print("Hi")
exit()
if
Run Code Online (Sandbox Code Playgroud) 我们可以转发声明一个函数:
void func1();
void func2() {
// use func1
}
void func1() {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
func1如果调用以下命令,这可能是必要的func2:
void func1();
void func2() {
func1();
}
void func1() {
if (condition) {
func2();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然func1第二个示例中的内联并不困难,但我不知道在任意复杂的程序中是否存在此类编译器优化的理论障碍。在第二种情况下,前向声明是必要的,并且可能会丢失与程序的递归性质相关的编译器优化。
问题:当不需要但仍然使用前向声明时(例如第一个示例),任何主要编译器(gcc、clang、msvc)上是否会丢失任何编译器优化?
c++ optimization recursion forward-declaration compiler-optimization
我正在寻找一些示例std::visit,并且我想探索一下以下常见示例代码:
#include <iostream>
#include <variant>
struct Fluid { };
struct LightItem { };
struct HeavyItem { };
struct FragileItem { };
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>; // line not needed in C++20...
int main() {
std::variant<Fluid, LightItem, HeavyItem, FragileItem> package(HeavyItem{});
std::visit(overload{
[](Fluid& ) { std::cout << "fluid\n"; },
[](LightItem& ) { std::cout << "light item\n"; },
[](HeavyItem& ) { std::cout << "heavy item\n"; },
[](FragileItem& ) { std::cout …Run Code Online (Sandbox Code Playgroud) 最近,我和一位同事就 python 和 C++ 的性能比较进行了争论。我们俩主要使用这些语言来进行线性代数。所以我写了两个脚本,一个在 python3 中使用 numpy,另一个在 C++ 中使用 Eigen。
Python3 numpy版本matmul_numpy.py:
import numpy as np
import time
a=np.random.rand(2000,2000)
b=np.random.rand(2000,2000)
start=time.time()
c=a*b
end=time.time()
print(end-start)
Run Code Online (Sandbox Code Playgroud)
如果我运行这个脚本
python3 matmul_numpy.py
Run Code Online (Sandbox Code Playgroud)
这将返回:
0.07 seconds
Run Code Online (Sandbox Code Playgroud)
C++ 特征版本 matmul_eigen.cpp:
#include <iostream>
#include <Eigen/Dense>
#include "time.h"
int main(){
clock_t start,end;
size_t n=2000;
Eigen::MatrixXd a=Eigen::MatrixXd::Random(n,n);
Eigen::MatrixXd b=Eigen::MatrixXd::Random(n,n);
start=clock();
Eigen::MatrixXd c=a*b;
end=clock();
std::cout<<(double)(end-start)/CLOCKS_PER_SEC<<std::endl;
return 0;}
Run Code Online (Sandbox Code Playgroud)
我编译的方式是
g++ matmul_eigen.cpp -I/usr/include/eigen3 -O3 -march=native -std=c++17 -o matmul_eigen
Run Code Online (Sandbox Code Playgroud)
这将返回(c++11 和 c++17):
0.35 seconds
Run Code Online (Sandbox Code Playgroud)
这对我来说很奇怪,1-为什么 numpy 这里比 C++ 更快?我是否缺少任何其他优化标志?
我想也许是因为 python 解释器在这里执行程序更快。因此,我使用stacks …
c++ ×6
assembly ×2
c ×1
compilation ×1
eigen3 ×1
for-loop ×1
gcc ×1
java ×1
numpy ×1
optimization ×1
python ×1
python-3.x ×1
recursion ×1
simd ×1
sse ×1
stl ×1
visual-c++ ×1
x86-64 ×1