这是一段看似非常特殊的C++代码.出于某种奇怪的原因,奇迹般地对数据进行排序使得代码几乎快了六倍.
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster.
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c) …Run Code Online (Sandbox Code Playgroud) 当您.exe在 Windows 中运行控制台应用程序(例如用 C++ 编写的应用程序)时,Windows 会为您创建一个控制台窗口。
因此,本质上,该程序不会在 Windows 本身以外的任何东西上运行。
当您java Main.class 在cmd.exe 控制台内部调用时,它真的是它自己的独立程序吗?感觉更像java是程序在运行,Main.class只是给出了一个参数。
所有这一切都是为了问,所有的Java程序都只是控制台java [argument]程序吗?另一种问法是,所有 Java 程序都只是读取特定类文件的 JRE 程序/实例吗?
我已经和C一起工作了一段时间,最近才开始进入ASM.当我编译一个程序时:
int main(void)
{
int a = 0;
a += 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
objdump反汇编有代码,但在ret之后nops:
...
08048394 <main>:
8048394: 55 push %ebp
8048395: 89 e5 mov %esp,%ebp
8048397: 83 ec 10 sub $0x10,%esp
804839a: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
80483a1: 83 45 fc 01 addl $0x1,-0x4(%ebp)
80483a5: b8 00 00 00 00 mov $0x0,%eax
80483aa: c9 leave
80483ab: c3 ret
80483ac: 90 nop
80483ad: 90 nop
80483ae: 90 nop
80483af: 90 nop
...
Run Code Online (Sandbox Code Playgroud)
从我学到的东西,什么都不做,因为ret之后甚至都不会被执行.
我的问题是:为什么要这么麻烦?ELF(linux-x86)无法使用任何大小的.text段(+ main)吗? …
我一直试图通过计算一个使用以下代码对数组元素进行扩展和求和的例程来了解在L1缓存与内存中使用数组的影响(我知道我应该将结果缩放为' a'在最后;关键是在循环中同时进行乘法和加法 - 到目前为止,编译器还没有想出要将'a'分解出来):
double sum(double a,double* X,int size)
{
double total = 0.0;
for(int i = 0; i < size; ++i)
{
total += a*X[i];
}
return total;
}
#define KB 1024
int main()
{
//Approximately half the L1 cache size of my machine
int operand_size = (32*KB)/(sizeof(double)*2);
printf("Operand size: %d\n", operand_size);
double* X = new double[operand_size];
fill(X,operand_size);
double seconds = timer();
double result;
int n_iterations = 100000;
for(int i = 0; i < n_iterations; ++i)
{
result = …Run Code Online (Sandbox Code Playgroud) 我正在尝试将整个流(多行)读成字符串.
我正在使用这个代码,它有效,但它冒犯了我的风格......当然有一种更简单的方法吗?也许使用stringstreams?
void Obj::loadFromStream(std::istream & stream)
{
std::string s;
std::streampos p = stream.tellg(); // remember where we are
stream.seekg(0, std::ios_base::end); // go to the end
std::streamoff sz = stream.tellg() - p; // work out the size
stream.seekg(p); // restore the position
s.resize(sz); // resize the string
stream.read(&s[0], sz); // and finally, read in the data.
Run Code Online (Sandbox Code Playgroud)
const对字符串的引用也可以,这可能会使事情变得更容易......
const std::string &s(... a miracle occurs here...)
Run Code Online (Sandbox Code Playgroud) 我正在使用 GCC 为 ARM 开发 C++。我遇到了一个问题,我没有启用优化,我无法为我的代码创建二进制文件(ELF),因为它不适合可用空间。但是,如果我只是启用调试优化(-Og)(据我所知这是可用的最低优化),代码就很容易适应。
在这两种情况下,都会启用-ffunction-sections、-fdata-sections、-fno-exceptions和-Wl,--gc-sections 。
即使进行了最小的优化,二进制大小也存在巨大差异。
我查看了3.11 控制优化的选项,详细了解使用 -Og 标志执行哪些优化,看看这是否会给我任何见解。
哪些优化标志对二进制大小影响最大?我应该寻找什么来解释这种巨大的差异吗?
所以,用下面的代码,改变参数的类型x从const ull到const ull&(有typedef unsigned long long ull)在约25%的加速效果,当用gcc 4.7.2和标志编译-O3 -std=c++11 -g,我想不通为什么会做出如此大的差异.
static void inline single_mult(const std::vector<ull>::iterator& data,
const std::vector<ull>::const_iterator& rbegin,
const std::vector<ull>::const_iterator& rend,
const ull x) {
ull tmp=0, carry=0, i=0;
for (auto rhs_it = rbegin; rhs_it != rend; ++rhs_it) {
tmp = x*(*rhs_it) + data[i] + carry;
if (tmp >= imax) {
carry = tmp >> numbits;
tmp &= imax - 1;
} else {
carry = 0;
}
data[i++] …Run Code Online (Sandbox Code Playgroud) 我将分支目标与NOP对齐,有时CPU执行这些NOP,最多15个NOP.Skylake可以在一个周期内执行多少个1字节NOP?其他与AMD兼容的处理器如何?我不仅对Skylake感兴趣,而且对其他微架构也感兴趣.执行一系列15个NOP可能需要多少个周期?我想知道增加这些NOP的额外代码大小和额外执行时间是否物有所值.这不是我添加这些NOP而是每当我编写align指令时自动添加汇编程序的人.
更新:我已经设法自动插入多字节NOPs.
我有一个严重的网络I/O绑定的C应用程序.它目前-O2在gcc上编译.使用-Os节目构建应用程序可以减少20%的大小.一些基本测试显示性能没有可测量的降低(或增加).
这是一个建设的好例子-Os吗?有没有理由不这样做?我从来没有真正看到过编译过程的程序,无论它在I/O上花费多少时间.
我正在编写一些代码来读取位图文件。
这是我用来读取位图标头的结构。也可以看看:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
struct BITMAPFILEHEADER
{
WORD bfType; // 2
DWORD bfSize; // 6
WORD bfReserved1; // 8
WORD bfReserved2; // 10
DWORD bfOffBits; // 14
}; // should add to 14 bytes
Run Code Online (Sandbox Code Playgroud)
如果我将以下代码放在我的主函数中:
std::cout << "BITMAPFILEHEADER: " << sizeof(BITMAPFILEHEADER) << std::endl;
Run Code Online (Sandbox Code Playgroud)
该程序打印:
BITMAPFILEHEADER: 16
Run Code Online (Sandbox Code Playgroud)
它似乎是在 4 字节边界上重新对齐结构中的数据,大概是为了效率。当然,这使我无法读取位图......即使微软和其他人,指定这是这样做的方式......
如何防止结构重新对齐?
我用 C 编写了众所周知的交换函数,并使用 gcc S 观看了汇编输出,并再次做了同样的事情,但对 O2 进行了优化
差异非常大,因为与 20 行相比,我只看到了 5 行。
我的问题是,如果优化真的有帮助,为什么不一直使用它?为什么我们非优化编译代码?
给业内人士一个额外的问题,当您在测试后发布程序的最终版本时,您是否进行了优化编译?
我正在回复您的所有评论,请阅读。