对于浮点值,是否保证a + b == b + a?
我相信这在IEEE754中是有保证的,但是C++标准没有规定必须使用IEEE754.唯一相关的文本似乎来自[expr.add]#3:
binary +运算符的结果是操作数的总和.
数学运算"和"是可交换的.然而,数学运算"sum"也是关联的,而浮点加法肯定不是关联的.所以,在我看来,我们不能断定数学中"和"的交换性意味着这个引用指的是C++中的交换性.
给定n部分和,可以将log2并行步骤中的所有部分和相加.例如,假设有八个线程与八个部分和:s0, s1, s2, s3, s4, s5, s6, s7.这可以在这样的log2(8) = 3连续步骤中减少;
thread0 thread1 thread2 thread4
s0 += s1 s2 += s3 s4 += s5 s6 +=s7
s0 += s2 s4 += s6
s0 += s4
Run Code Online (Sandbox Code Playgroud)
我想用OpenMP做这个,但我不想使用OpenMP的reduction子句.我想出了一个解决方案,但我认为可以使用OpenMP的task子句找到更好的解决方案.
这比标量加法更通用.让我选择一个更有用的情况:一个数组减少(见这里,这里,并在这里为更多关于阵列减少).
假设我想在阵列上进行数组缩减a.下面是一些代码,它们为每个线程并行填充私有数组.
int bins = 20;
int a[bins];
int **at; // array of pointers to arrays
for(int i = 0; i<bins; i++) a[i] = 0;
#pragma omp …Run Code Online (Sandbox Code Playgroud) 我有以下功能:
void CopyImageBitsWithAlphaRGBA(unsigned char *dest, const unsigned char *src, int w, int stride, int h,
unsigned char minredmask, unsigned char mingreenmask, unsigned char minbluemask, unsigned char maxredmask, unsigned char maxgreenmask, unsigned char maxbluemask)
{
auto pend = src + w * h * 4;
for (auto p = src; p < pend; p += 4, dest += 4)
{
dest[0] = p[0]; dest[1] = p[1]; dest[2] = p[2];
if ((p[0] >= minredmask && p[0] <= maxredmask) || (p[1] >= mingreenmask …Run Code Online (Sandbox Code Playgroud) 我必须对相对较小的整数进行大量操作(加法),并且我开始考虑哪种数据类型在 64 位机器上能提供最佳性能。
\n我确信uint16将 4 加在一起所需的时间与 1 相同uint64,因为 ALU 可以uint16仅使用 1 个uint64加法器进行 4 次加法。(进位传播意味着这对于单个 64 位加法器来说并不容易,但这就是整数 SIMD 指令的工作原理。)
显然情况并非如此:
\nIn [3]: data = np.random.rand(10000)\n\nIn [4]: int16 = data.astype(np.uint16)\n\nIn [5]: int64 = data.astype(np.uint64)\n\nIn [6]: int32 = data.astype(np.uint32)\n\nIn [7]: float32 = data.astype(np.float32)\n\nIn [8]: float64 = data.astype(np.float64)\n\nIn [9]: %timeit int16.sum()\n13.4 \xc2\xb5s \xc2\xb1 43.3 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n\nIn [10]: %timeit int32.sum()\n13.9 \xc2\xb5s \xc2\xb1 347 …Run Code Online (Sandbox Code Playgroud) 为了学术目的,我在 C++ 中使用了基本的数学函数实现。今天,我对以下平方根代码进行了基准测试:
inline float sqrt_new(float n)
{
__asm {
fld n
fsqrt
}
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶地看到它始终比标准sqrt函数快(它需要标准函数执行时间的 85% 左右)。
我不太明白为什么,很想更好地理解它。下面我展示了我用来分析的完整代码(在 Visual Studio 2015 中,在发布模式下编译并打开所有优化):
#include <iostream>
#include <random>
#include <chrono>
#define M 1000000
float ranfloats[M];
using namespace std;
inline float sqrt_new(float n)
{
__asm {
fld n
fsqrt
}
}
int main()
{
default_random_engine randomGenerator(time(0));
uniform_real_distribution<float> diceroll(0.0f , 1.0f);
chrono::high_resolution_clock::time_point start1, start2;
chrono::high_resolution_clock::time_point end1, end2;
float sqrt1 = 0;
float sqrt2 = 0;
for (int i = 0; i<M; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用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)