我回答了this question ,并注意到我认为编译器的一种奇怪行为。
我首先编写了这个程序(作为我在那里回答的一部分):
class Vector {
private:
double** ptr;
public:
Vector(double** _ptr): ptr(_ptr) {}
inline double& operator[](const int iIndex) const {
return *ptr[iIndex];
}
};
extern "C" int test(const double a);
int main() {
double a[2] = { 1.0, 2.0 };
Vector va((double**) &a);
double a1 = va[0];
test(a1);
double a2 = va[0];
test(a2);
}
编译时生成两条加载指令:
clang -O3 -S -emit-llvm main.cpp -o main.ll
这可以在 llvm-IR 中看到(也可以在程序集中看到):
define i32 @main() #0 {
entry:
%a.sroa.0.0.copyload = load double*, double** bitcast ([2 x double]* @_ZZ4mainE1a to double**), align 16
%0 = load double, double* %a.sroa.0.0.copyload, align 8, !tbaa !2
%call1 = tail call i32 @test(double %0)
%1 = load double, double* %a.sroa.0.0.copyload, align 8, !tbaa !2
%call3 = tail call i32 @test(double %1)
ret i32 0
}
I would expect only one load instruction, since no function with side effect on memory has been called, and I didn't link this object to something with side effects. In fact, when reading the program, I just expect two calls to
test(1.0);
因为我的数组在内存中是常量,所有内容都可以正确内联。
为了确定,我用一个简单的指针替换了双指针:
class Vector {
private:
double* ptr;
public:
Vector(double* _ptr): ptr(_ptr) {}
inline double& operator[](const int iIndex) const {
return ptr[iIndex];
}
};
extern "C" int test(const double a);
int main() {
double a[2] = { 1.0, 2.0 };
Vector va(a);
double a1 = va[0];
test(a1);
double a2 = va[0];
test(a2);
}
用同一行编译,我得到了预期的结果:
define i32 @main() #0 {
entry:
%call1 = tail call i32 @test(double 1.000000e+00)
%call3 = tail call i32 @test(double 1.000000e+00)
ret i32 0
}
看起来优化得更好:)
因此我的问题是:
什么原因阻止编译器对第一个代码示例执行相同的内联?那是双指针吗?
最佳答案
错误在这些行中:
double a[2] = { 1.0, 2.0 };
Vector<double> va((double**) &a);
a 是两个 double 组。它衰减为double *,但&a不是 double ** . 数组和指针不是同一种动物。
事实上你有以下内容:(void *) a == (void *) &a 因为数组的地址是它的第一个元素的地址。
如果你想构建一个指向指针的指针,你必须明确地创建一个真正的指针:
double a[2] = { 1.0, 2.0 };
double *pt = a; // or &(a[0]) ...
Vector<double> va((double**) &pt);
关于c++ - 指针上的指针 - 性能损失的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37323517/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到
我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“