我正在开发一些工程模拟.这包括实现一些长方程,例如这个方程,以计算橡胶类材料中的应力:
T = (
mu * (
pow(l1 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a
* (
pow(l1 * l2 * l3, -0.1e1 / 0.3e1)
- l1 * l2 * l3 * pow(l1 * l2 * l3, -0.4e1 / 0.3e1) / 0.3e1
) * pow(l1 * l2 * l3, 0.1e1 / 0.3e1) / l1
- pow(l2 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l1 / 0.3e1
- pow(l3 * …Run Code Online (Sandbox Code Playgroud) 使用此代码有什么好处
double x;
double square = pow(x,2);
Run Code Online (Sandbox Code Playgroud)
而不是这个?
double x;
double square = x*x;
Run Code Online (Sandbox Code Playgroud)
我更喜欢x*x并且查看我的实现(Microsoft)我发现pow没有优势,因为x*x比特定方形情况下的pow更简单.
有什么特别的情况,战俘优越吗?
我写了这个:
var max = 0xffffff * 4;
var step = 1 / max;
function cube() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x * x;
}
return result;
}
function mul() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x;
}
return result;
}
function go() {
var r = '';
r += …Run Code Online (Sandbox Code Playgroud) 我是指令优化的新手.
我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.
C代码如下:
float dotp(
const float x[],
const float y[],
const short n
)
{
short i;
float suma;
suma = 0.0f;
for(i=0; i<n; i++)
{
suma += x[i] * y[i];
}
return suma;
}
Run Code Online (Sandbox Code Playgroud)
我用昂纳雾在网络上提供的测试框架testp.
在这种情况下使用的数组是对齐的:
int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);
float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)
然后我调用函数dotp,n = 2048,repeat …
在C代码中,通常写
a = b*b;
Run Code Online (Sandbox Code Playgroud)
代替
a = pow(b, 2.0);
Run Code Online (Sandbox Code Playgroud)
对于double变量.我知道因为它pow是一个能够处理非整数指数的通用函数,所以应该天真地认为第一个版本更快.我不知道编译器(gcc)是否将调用转换为pow整数指数,以指示乘法作为任何可选优化的一部分.
假设没有进行这种优化,那么手动写出乘法的最大整数指数是b*b* ... *b多少,如?
我知道我可以在给定的机器上进行性能测试,以确定我是否应该关心,但我想更深入地了解什么是"正确的事情".
我对c/c ++的(部分)编译时评估非常感兴趣(不是像c ++中的模板参数).让我们考虑以下情况(取自[1]):
double mypower(double x, int n) {
int i;
double ret = x;
for (i = 1; i < n; i++) {
ret *= x;
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
然后在代码中的某处调用此函数:
mypower(x,3); // y varies all the time,
Run Code Online (Sandbox Code Playgroud)
然后编译器可以优化它(例如循环展开).我使用的一些常用函数可以从优化中获益(通过手动创建专用函数进行测试).演示文稿[1]描述了一个搜索函数的过程,并由函数的专用版本替换.这似乎有效.但它似乎并不是非常普遍,需要为应该替换的函数编写代码.
该演示文稿似乎是从2008年开始,我找不到比此来源更多的信息.那么从那时起有什么改进吗?我更喜欢某种自动化,它对可能由属性语法控制的所有函数都做同样的事情(例如__attribute__(peval)......).此外,我希望同样适用于面向对象的代码,为不同的对象创建专门的类([2]似乎暗示这是不可能的).
另外,我希望这种专业化不仅适用于代码中的常量.我正在考虑编译为LLVM IR(字节码)的程序可以执行以下操作:
在解释器的初始化阶段运行程序,在初始化阶段,程序可以从文件中读取一些配置.初始化后,解释器停止.
从那一点开始修复一些变量(包括成员变量).提取这些变量(例如,在编译期间由属性标记).
创建专门的函数和类.将这些克隆到字节码中.
运行JIT以创建本机机器代码.
这是我要求的很多,只有少数计算密集型程序可以从这种优化中受益.但是有些人必须在努力.我可能只是不知道正确的搜索条件来提供谷歌.
注意:请不要建议使用非类型参数或手动专业化的模板类,我已经这样做了.我只是希望编译器为我工作.
链接:
[1] 介绍如何在LLVM中进行部分评估
[2] 关于部分评估的论坛信息
我正在尝试使用simd内部函数在C中编程矩阵乘法。我非常确定自己的实现,但是执行时,我会从所得矩阵系数的第5位开始出现一些数字错误。
REAL_T只是具有typedef的浮点数
/* This is my matmul Version with simd, using floating simple precision*/
void matmul(int n, REAL_T *A, REAL_T *B, REAL_T *C){
int i,j,k;
__m256 vA, vB, vC, vRes;
for (i=0; i<n; i++){
for (j=0; j<n; j++){
for (k=0; k<n; k= k+8){
vA = _mm256_load_ps(&A[i*n+k]);
vB = _mm256_loadu_ps(&B[k*n+j]);
vC = _mm256_mul_ps(vA, vB);
vC = _mm256_hadd_ps(vC, vC);
vC = _mm256_hadd_ps(vC, vC);
/*To get the resulting coefficient, after doing 2 hadds,
I have to get the first and the last element …Run Code Online (Sandbox Code Playgroud) 在做我的作业时,我注意到一些非常奇怪的东西,我无法弄清楚为什么.
int x = 5;
cout << pow(x, 2);
Run Code Online (Sandbox Code Playgroud)
结果是25.那没关系.但如果我写这样的程序:
int x = 5;
int y = pow(x, 2);
cout << y;
Run Code Online (Sandbox Code Playgroud)
结果是24!
当x为2,3,4,6,7,8没有问题,但是5,10,11,13等结果比它应该低1.
if()也是一样的.
for (int x = 1; x <= 20 ; x++) {
if (x * x == pow(x, 2))
cout << x << endl;
}
Run Code Online (Sandbox Code Playgroud)
它打印出数字1,2,3,4,6,8,12,16.
我正在做一个简单的家庭作业,我必须在C中开发一个软件,找到100个之间的两个最近的点.
当我完成时,我很想知道需要花多少时间才能运行它并获得更多积分并启用完整的VC++优化.我尝试了10000,花了大约8~9秒.然后我很想知道C#和Java花多少时间做同样的事情.正如预期的那样,C#需要更长的时间,9~10秒; 然而,Java只花了大约400毫秒!为什么会这样?!
这是我在C,C#和Java中的代码:
C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Windows.h>
long perfFrequency = 0;
typedef struct
{
double X;
double Y;
} Point;
double distance(Point p1, Point p2)
{
return sqrt(pow(p1.X - p2.X, 2) + pow(p1.Y - p2.Y, 2));
}
double smallerDistance(Point *points, int size, Point *smallerA, Point *smallerB)
{
int i, j;
double smaller = distance(points[0], points[1]);
for (i = 0; i < size; i++)
{
for (j = i + 1; j < size; j++) …Run Code Online (Sandbox Code Playgroud) 对我的 C++ 代码进行分析后,发现该pow函数被大量使用。
我的一些pow函数有一个整数指数和另一个非整数指数。我只对整数指数感兴趣。
为了提高性能,我正在寻找一种定义宏的方法,如下所示:
#define pow(x,n) ({\
double product;\
if (typeid(n).name() == "i") {\
for(int i = 0; i < n-1; i++)\
product *= x;}\
else\
product = pow(x,n);\
product;\
})
Run Code Online (Sandbox Code Playgroud)
但我没有得到关于运行时间的预期收益。我认为这是由于else我的宏中我称之为经典pow函数的部分所致。
如何在预处理期间“写入”宏之前提前确定指数类型?
理想情况下,我希望仅在指数是整数时应用此宏,但似乎我的尝试不相关。
根据您的建议,我尝试了三种选择:
第一个选项:只需添加重载内联函数,其基数为integeror double:
// First option
inline int pow(int x, int n){
// using simple mechanism for repeated multiplication
int product = 1;
for(int i = 0; i < n; i++){
product *= x; …Run Code Online (Sandbox Code Playgroud) c++ ×7
optimization ×5
c ×4
performance ×3
math ×2
pow ×2
assembly ×1
avx ×1
c# ×1
evaluation ×1
g++ ×1
gcc ×1
gnu ×1
java ×1
javascript ×1
llvm ×1
macros ×1
partial ×1
preprocessor ×1
simd ×1
sse ×1