代码的目的是找到32位浮点位模式的总数,它代表0到1之间的值.在我看来这应该可行,但由于某种原因,Clang的汇编输出基本上相当于return 0;.
我使用-std=c++1y -Wall -Wextra -pedantic -O2和编译了Clang 3.3和Clang 3.4.1-std=c++1y -Wall -Wextra -pedantic -O3
Clang 3.4使用-O2和-O3优化一切.
Clang 3.3仅使用-O3优化一切.
通过"优化一切",我的意思是这是程序的汇编输出:
main: # @main
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
#include <limits>
#include <cstring>
#include <cstdint>
template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
TO out;
std::memcpy(&out, &input, sizeof(TO));
return out;
}
int main()
{
uint32_t i = std::numeric_limits<uint32_t>::min();
uint32_t count = 0;
while (1)
{
float n = punning_cast<float>(i);
if(n >= 0.0f && n <= 1.0f) …Run Code Online (Sandbox Code Playgroud) 我的C++代码使用SSE,现在我想改进它以支持AVX可用时.所以我检测AVX何时可用并调用使用AVX命令的函数.我使用Win7 SP1 + VS2010 SP1和带AVX的CPU.
要使用AVX,必须包含以下内容:
#include "immintrin.h"
Run Code Online (Sandbox Code Playgroud)
然后你可以使用内在的AVX函数_mm256_mul_ps,_mm256_add_ps等等.问题是,默认情况下,VS2010产生的代码工作得非常慢,并显示警告:
警告C4752:发现英特尔(R)高级矢量扩展; 考虑使用/ arch:AVX
似乎VS2010实际上不使用AVX指令,而是模仿它们.我添加/arch:AVX到编译器选项并获得了良好的结果.但是这个选项告诉编译器尽可能在任何地方使用AVX命令.所以我的代码可能会崩溃在不支持AVX的CPU上!
所以问题是如何使VS2010编译器生成AVX代码,但只有当我直接指定AVX内在函数时.对于它工作的SSE,我只使用SSE内在函数,它产生SSE代码,没有任何编译器选项,如/arch:SSE.但对于AVX而言,由于某些原因它不起作用.
当我用VC++ 10编译这段代码时:
DWORD ran = rand();
return ran / 4096;
Run Code Online (Sandbox Code Playgroud)
我得到这个反汇编:
299: {
300: DWORD ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 shr eax,0Ch
302: }
00403949 ret
Run Code Online (Sandbox Code Playgroud)
这是一个干净,简洁,用一个逻辑右移的2的幂代替一个除法.
然而,当我编译这段代码时:
int ran = rand();
return ran / 4096;
Run Code Online (Sandbox Code Playgroud)
我得到这个反汇编:
299: {
300: int ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 cdq
00403947 and edx,0FFFh
0040394D add eax,edx
0040394F sar eax,0Ch
302: }
00403952 ret …Run Code Online (Sandbox Code Playgroud) 有没有可行的分支预测提示方法?请考虑以下示例:
if (unlikely_condition) {
/* ..A.. */
} else {
/* ..B.. */
}
Run Code Online (Sandbox Code Playgroud)
这有什么不同于:
if (!unlikely_condition) {
/* ..B.. */
} else {
/* ..A.. */
}
Run Code Online (Sandbox Code Playgroud)
或者是使用编译器特定提示的唯一方法?(例如海湾合作委员会的__builtin_expect)
编译器会根据if条件的顺序对条件进行不同的处理吗?
在编译时gcc -O3,为什么以下循环没有矢量化(自动):
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foo () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] = b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
Run Code Online (Sandbox Code Playgroud)
什么时候呢?
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foov () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] += b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
Run Code Online (Sandbox Code Playgroud)
唯一的区别在于内部循环中的表达式的结果是 …
以C++编写的一个数值软件的以下关键循环基本上将两个对象的成员比较:
for(int j=n;--j>0;)
asd[j%16]=a.e<b.e;
Run Code Online (Sandbox Code Playgroud)
a和b是类ASD:
struct ASD {
float e;
...
};
Run Code Online (Sandbox Code Playgroud)
我正在调查将此比较放在轻量级成员函数中的效果:
bool test(const ASD& y)const {
return e<y.e;
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
for(int j=n;--j>0;)
asd[j%16]=a.test(b);
Run Code Online (Sandbox Code Playgroud)
编译器正在内联这个函数,但问题是,汇编代码会有所不同,导致运行时开销超过10%.我要问:
为什么编译器会推出不同的汇编代码?
为什么生产的组件更慢?
编辑: 第二个问题已通过实施@ KamyarSouri的建议(j%16)得到了回答.汇编代码现在看起来几乎相同(请参阅http://pastebin.com/diff.php?i=yqXedtPm).唯一的区别是第18,33,48行:
000646F9 movzx edx,dl
Run Code Online (Sandbox Code Playgroud)
此图表显示了我的代码的50个测试的FLOP/s(最多为缩放因子).

用于生成绘图的gnuplot脚本:http://pastebin.com/8amNqya7
编译器选项:
/ Zi/W3/WX-/MP/Ox/Ob2/Oi/Ot/Oy/GL/D"WIN32"/ D"NDEBUG"/ D"_CONSOLE"/ D"_UNICODE"/ D"UNICODE"/ Gm-/EHsc/MT/GS-/Gy/arch:SSE2/fp:exact/Zc:wchar_t/Zc:forScope/Gd/analyze-
链接器选项:/ INCREMENTAL:NO"kernel32.lib""user32.lib""gdi32.lib""winspool.lib""comdlg32.lib""advapi32.lib""shell32.lib""ole32.lib""oleaut32. lib""uuid.lib""odbc32.lib""odbccp32.lib"/ ALLOWISOLATION/MANIFESTUAC:"level ='asInvoker'uiAccess ='false'"/ SUBSYSTEM:CONSOLE/OPT:REF/OPT:ICF/LTCG/TLBID …
我有以下问题:
写时间到std::array用于int8,int16,int32和int64与每个尺寸增加一倍.我可以理解8位CPU的这种行为,但不能理解32/64位.
为什么32位系统需要4倍的时间来保存32位值而不是保存8位值?
这是我的测试代码:
#include <iostream>
#include <array>
#include <chrono>
std::array<std::int8_t, 64 * 1024 * 1024> int8Array;
std::array<std::int16_t, 64 * 1024 * 1024> int16Array;
std::array<std::int32_t, 64 * 1024 * 1024> int32Array;
std::array<std::int64_t, 64 * 1024 * 1024> int64Array;
void PutZero()
{
auto point1 = std::chrono::high_resolution_clock::now();
for (auto &v : int8Array) v = 0;
auto point2 = std::chrono::high_resolution_clock::now();
for (auto &v : int16Array) v = 0;
auto point3 = std::chrono::high_resolution_clock::now();
for …Run Code Online (Sandbox Code Playgroud) 我是第一次在STL库中使用vector类.我应该如何添加到矢量数组的特定行?
struct x{
vector <vector <int> > v;
int row;
};
vector< int* > my ints;
int add;
Run Code Online (Sandbox Code Playgroud)
如果我想用第一个整数指针添加到第一行v,我能做到吗?
myints[0]->v[myints[0]->row].push_back(add);
Run Code Online (Sandbox Code Playgroud)
这种方法是否可以创建向量ints的二维向量,其中每一行可能具有不同的长度(即具有不同的列数)?
我正在编写一个图像处理程序来执行视频帧的实时处理.它是在C#中使用包装OpenCV库dll(非托管C++)的Emgu.CV库(C#).现在我必须编写自己的特殊算法,它需要尽可能快.
哪个算法的实现速度更快?
在C#中编写'不安全'函数
将该函数添加到OpenCV库并通过Emgu.CV调用它
我猜C#unsafe比较慢,因为它是通过JIT编译器,但差异是否显着?
编辑:
在VS2008下编译为.NET 3.5
gcc 4.4.4下面的简单代码段错误
#include<stdio.h>
typedef struct Foo Foo;
struct Foo {
char f[25];
};
Foo foo(){
Foo f = {"Hello, World!"};
return f;
}
int main(){
printf("%s\n", foo().f);
}
Run Code Online (Sandbox Code Playgroud)
将最后一行更改为
Foo f = foo(); printf("%s\n", f.f);
Run Code Online (Sandbox Code Playgroud)
工作良好.这两个版本在编译时都有效-std=c99.我只是调用未定义的行为,或者标准中的某些内容已更改,这允许代码在C99下工作?为什么在C89下崩溃?