我一直在寻找最快的方法来处理popcount大数据.我遇到了一个很奇怪的效果:改变从循环变量unsigned至uint64_t50%在我的电脑上所做的性能下降.
#include <iostream>
#include <chrono>
#include <x86intrin.h>
int main(int argc, char* argv[]) {
using namespace std;
if (argc != 2) {
cerr << "usage: array_size in MB" << endl;
return -1;
}
uint64_t size = atol(argv[1])<<20;
uint64_t* buffer = new uint64_t[size/8];
char* charbuffer = reinterpret_cast<char*>(buffer);
for (unsigned i=0; i<size; ++i)
charbuffer[i] = rand()%256;
uint64_t count,duration;
chrono::time_point<chrono::system_clock> startP,endP;
{
startP = chrono::system_clock::now();
count = 0;
for( unsigned k = 0; k < …Run Code Online (Sandbox Code Playgroud) 我已经读过将函数指针转换为数据指针,反之亦然,但在大多数平台上都可以工作,但不能保证工作.为什么会这样?两者都不应该只是简单地址到主存储器中,因此兼容吗?
默认方法是我们的Java工具箱中一个不错的新工具.但是,我尝试编写一个定义default该toString方法版本的接口.Java告诉我这是禁止的,因为声明的方法java.lang.Object可能不会被default编辑.为什么会这样?
我知道存在"基类永远胜利"规则,因此默认情况下(pun;),方法的任何default实现Object都会被方法覆盖Object.但是,我认为没有理由说明Object规范中的方法不应该有例外.特别是对于toString具有默认实现可能非常有用.
那么,Java设计者决定不允许default方法覆盖方法的原因是什么Object?
我最近遇到了一个奇怪的去优化(或者错过了优化机会).
考虑此函数可以有效地将3位整数数组解包为8位整数.它在每次循环迭代中解包16个int:
void unpack3bit(uint8_t* target, char* source, int size) {
while(size > 0){
uint64_t t = *reinterpret_cast<uint64_t*>(source);
target[0] = t & 0x7;
target[1] = (t >> 3) & 0x7;
target[2] = (t >> 6) & 0x7;
target[3] = (t >> 9) & 0x7;
target[4] = (t >> 12) & 0x7;
target[5] = (t >> 15) & 0x7;
target[6] = (t >> 18) & 0x7;
target[7] = (t >> 21) & 0x7;
target[8] = (t >> 24) & 0x7;
target[9] = …Run Code Online (Sandbox Code Playgroud) c++ optimization strict-aliasing compiler-optimization c++11
我有一个名称隐藏问题,这是一个非常难以解决的问题.这是一个解释问题的简化版本:
有一节课: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Run Code Online (Sandbox Code Playgroud)
然后是一堂课 net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
Run Code Online (Sandbox Code Playgroud)
而现在,这是一个有问题的类,它继承A并且想要调用net.foo.X.doSomething()
package com.bar;
class B extends A {
public void doSomething(){
net.foo.X.doSomething(); // doesn't work; package net is hidden by inherited field
X.doSomething(); // doesn't work; type net.foo.X is hidden by inherited X
}
}
Run Code Online (Sandbox Code Playgroud)
如你所见,这是不可能的.我不能使用简单名称,X因为它被继承的类型隐藏.我无法使用完全限定名称net.foo.X,因为net它被继承的字段隐藏.
只有类B在我的代码库中; 类net.foo.X和org.A …
考虑我有以下代码:
class Foo {
Y func(X x) {...}
void doSomethingWithAFunc(Function<X,Y> f){...}
void hotFunction(){
doSomethingWithAFunc(this::func);
}
}
Run Code Online (Sandbox Code Playgroud)
假设hotFunction经常被调用.那么缓存是否可取this::func,也许是这样的:
class Foo {
Function<X,Y> f = this::func;
...
void hotFunction(){
doSomethingWithAFunc(f);
}
}
Run Code Online (Sandbox Code Playgroud)
就我对java方法引用的理解而言,虚拟机在使用方法引用时会创建匿名类的对象.因此,缓存引用将仅创建该对象一次,而第一种方法在每个函数调用上创建它.它是否正确?
是否应缓存出现在代码中热位置的方法引用,或者VM是否能够对此进行优化并使缓存变得多余?是否存在关于此的一般最佳实践,或者这种高度VM实现是否特定于此类缓存是否有用?
是否存在在C++(11)中解除分配局部变量的已定义顺序?更简洁:在同一范围内两个局部变量的析构函数的副作用会以何种顺序变为可见?
例如:
struct X{
~X(){/*do something*/}
}
int main(){
X x1;
X x2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是x1或x2毁坏第一主时返回或在C++ 11未定义的顺序?
我正在设置一些预处理器的东西,我想要一个更准确的数字,因为__cplusplusC++ 14应该被定义为.是否有一个标准强制要求?
我有一个非常奇怪的编译器行为,其中G ++将计算拉入热循环,严重降低了生成的代码的性能.这里发生了什么?
考虑这个功能:
#include <cstdint>
constexpr bool noLambda = true;
void funnyEval(const uint8_t* columnData, uint64_t dataOffset, uint64_t dictOffset, int32_t iter, int32_t limit, int32_t* writer,const int32_t* dictPtr2){
// Computation X1
const int32_t* dictPtr = reinterpret_cast<const int32_t*>(columnData + dictOffset);
// Computation X2
const uint16_t* data = (const uint16_t*)(columnData + dataOffset);
// 1. The less broken solution without lambda
if (noLambda) {
for (;iter != limit;++iter){
int32_t t=dictPtr[data[iter]];
*writer = t;
writer++;
}
}
// 2. The totally broken solution with lambda
else …Run Code Online (Sandbox Code Playgroud) 假设我有一个带有类型参数的函数T.它不会改变它,所以我可以选择通过const引用const T&或值传递它T:
void foo(T t){ ... }
void foo(const T& t){ ... }
Run Code Online (Sandbox Code Playgroud)
T在通过const引用变得比通过值便宜之前,是否应该有多大的经验法则?例如,假设我知道这一点sizeof(T) == 24.我应该使用const引用还是值?
我假设复制构造函数T是微不足道的.否则,问题的答案取决于复制构造函数的复杂性,当然.
我已经找了类似的问题,偶然发现了这个问题:
但是,接受的答案( /sf/answers/341385621/)没有说明任何细节,它只是声明:
如果您希望T始终是数字类型或复制非常便宜的类型,那么您可以按值获取参数.
所以它并没有解决我的问题,而是改写它:一种类型必须要"复制非常便宜"?
c++ ×7
c++11 ×3
java ×3
assembly ×2
java-8 ×2
optimization ×2
c ×1
c++14 ×1
caching ×1
destructor ×1
gcc ×1
interface ×1
name-clash ×1
performance ×1
pointers ×1
x86 ×1