hwliu11

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我参与的随笔

留言簿

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔档案

  • 2017年2月 (1)
  • 2016年4月 (1)
  • 2016年2月 (1)
  • 2015年11月 (2)

文章档案

  • 2020年11月 (1)

搜索

  •  

最新评论

  • 1. re: C/C++位运算的陷阱
  • 平时很少用位运算,这是教训吧啊@冬瓜
  • --刘慧伟
  • 2. re: C/C++位运算的陷阱
  • 这个是你对C++不了解好吧
  • --冬瓜

阅读排行榜

  • 1. Intel OpenMP运行时错误 OMP: Error #133 解决办法(932)
  • 2. GFORTRAN 64位openmp问题(621)
  • 3. C++智能指针类用不好害死人(592)
  • 4. OpenCASCADE 6.9.1 Bug(567)
  • 5. C/C++位运算的陷阱(392)

评论排行榜

  • 1. C/C++位运算的陷阱(2)
  • 2. GFORTRAN 64位openmp问题(0)
  • 3. C++智能指针类用不好害死人(0)
  • 4. OpenCASCADE 6.9.1 Bug(0)
  • 5. Intel OpenMP运行时错误 OMP: Error #133 解决办法(0)

Powered by: 博客园
模板提供:沪江博客
C++博客 | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

2017年2月4日

GFORTRAN 64位openmp问题
GFORTRAN在64位时候设置线程数目使用OMP_SET_NUM_THREADS无法生效,查看glibc代码,可以看出OMP_SET_NUM_THREADS是用C语言实现的,fortran参数传过来默认为地址,而OMP_SET_NUM_THREADS把传过来地址默认处理为32位地址,所以调用失败,64位下要使用专门处理64位地址的对应函数OMP_SET_NUM_THREADS_8_,上述两个函数输入参数不需要确认输入的integer是32位还是64位,这个与Intel Fortran不一样,Intel Fortran只是需要确认OMP_SET_NUM_THREADS的参数是32位还是64位
posted @ 2017-02-04 10:59 隔壁老刘 阅读(621) | 评论 (0) | 编辑 收藏
 

2016年4月12日

C/C++位运算的陷阱
昨天用C/C++写Base64编码,结果老是不对,
比如
unsigned char A =;
unsigned char B = ;
unsigned char C = ;
unsigned char a, b, c, d;
a = A >> 2;
b=(A << 6) >> 2|(B>>4);
c = ((B << 4)) >> 2) | (C >> 6);
d = (C << 2) >> 2;
结果发现bcd值都不对
但是写成
b = A<< 6;
b = b >> 2;
b=b|B>>4;
就可以,查看b计算两种方式汇编
第一种
00BACB66  movzx       eax,byte ptr [ebp-1F9h]  
00BACB6D  shl         eax,6  
00BACB70  sar         eax,2  
00BACB73  mov         byte ptr [ebp-1C9h],al  
第二种
00BACB79  movzx       eax,byte ptr [ebp-1F9h]  
00BACB80  shl         eax,6  
00BACB83  mov         byte ptr [ebp-1EDh],al  
00BACB89  movzx       eax,byte ptr [ebp-1EDh]  
00BACB90  sar         eax,2  
00BACB93  mov         byte ptr [ebp-1EDh],al  
问题就在指令sar,这是算数右移位指令,会保留最高位,而第二种可以是因为movzx  将高位已经置零
找到了原因,可以写为
a = A >> 2;
b=((unsigned char)(A << 6)) >> 2|(B>>4);
c = (((unsigned char)(B << 4)) >> 2) | (C >> 6);
d = ((unsigned char)(C << 2)) >> 2;
只要涉及到右移,保证操作数是无符号就可以了。
posted @ 2016-04-12 10:41 隔壁老刘 阅读(392) | 评论 (2) | 编辑 收藏
 

2016年2月27日

Intel OpenMP运行时错误 OMP: Error #133 解决办法
OMP: Error #133: Inconsistent THREADPRIVATE common block declarations are non-conforming and are unsupported. Either all threadprivate common blocks must be declared identically, or the largest instance of each threadprivate common block must be referenced first during the run.

发生以上错误确实很麻烦,而且可参考文档基本没有。Fortran代码中的Common块数据大小可以不一样大(相同名称的Common),但是在OpenMP中确要求,要么大小一样,要么占用内存最大的先调用,变量如果是隐式声明,一定要注意,变量名称不同,可能会编译为不同长度的内存
posted @ 2016-02-27 12:13 隔壁老刘 阅读(932) | 评论 (0) | 编辑 收藏
 

2015年11月12日

OpenCASCADE 6.9.1 Bug
OpenCASCADE 6.9.1(估计从6.9.0开始),使用新的屏幕选择算法,我使用6.8开发的程序,升级到6.9.1之后,使用IVTK部分模型无法选中几何元素,经过调试发现6.9.1代码有BUG,导致数据丢失,无法判断选中的元素是否在选择范围,BUG出现的文件为SelectMgr_RectangularFrustum.cxx中的函数ScaleAndTransform
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::ScaleAndTransform (const Standard_Integer theScaleFactor,
                                                                                           const gp_Trsf& theTrsf)
{
  Standard_ASSERT_RAISE (theScaleFactor > 0,
    "Error! Pixel tolerance for selection should be greater than zero");
  SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
  const Standard_Boolean isToScale = theScaleFactor != 1;
  const Standard_Boolean isToTrsf  = theTrsf.Form() != gp_Identity;
  if (!isToScale && !isToTrsf)
return aRes ;//这里,当部分模型满足该条件,返回一个空的数据,使用该数据无法判断模型是否在区域
  aRes->myIsOrthographic = myIsOrthographic;
  SelectMgr_RectangularFrustum* aRef = this;
  if (isToScale)
  {
    aRes->myNearPickedPnt = myNearPickedPnt;
    aRes->myFarPickedPnt  = myFarPickedPnt;
    aRes->myViewRayDir    = myViewRayDir;
    const gp_Pnt2d aMinPnt (myMousePos.X() - theScaleFactor * 0.5,
                            myMousePos.Y() - theScaleFactor * 0.5);
    const gp_Pnt2d aMaxPnt (myMousePos.X() + theScaleFactor * 0.5,
                            myMousePos.Y() + theScaleFactor * 0.5);
    // recompute base frustum characteristics from scratch
    computeFrustum (aMinPnt, aMaxPnt, myBuilder, aRes->myVertices, aRes->myEdgeDirs);
    aRef = aRes;
  }
  if (isToTrsf)
  {
    aRes->myNearPickedPnt = aRef->myNearPickedPnt.Transformed (theTrsf);
    aRes->myFarPickedPnt  = aRef->myFarPickedPnt.Transformed (theTrsf);
    aRes->myViewRayDir    = aRes->myFarPickedPnt.XYZ() - aRes->myNearPickedPnt.XYZ();
      // LeftTopNear
    aRes->myVertices[0] = aRef->myVertices[0].Transformed (theTrsf);
    // LeftTopFar
    aRes->myVertices[1] = aRef->myVertices[1].Transformed (theTrsf);
    // LeftBottomNear
    aRes->myVertices[2] = aRef->myVertices[2].Transformed (theTrsf);
    // LeftBottomFar
    aRes->myVertices[3] = aRef->myVertices[3].Transformed (theTrsf);
    // RightTopNear
    aRes->myVertices[4] = aRef->myVertices[4].Transformed (theTrsf);
    // RightTopFar
    aRes->myVertices[5] = aRef->myVertices[5].Transformed (theTrsf);
    // RightBottomNear
    aRes->myVertices[6] = aRef->myVertices[6].Transformed (theTrsf);
    // RightBottomFar
    aRes->myVertices[7] = aRef->myVertices[7].Transformed (theTrsf);
    // Horizontal
    aRes->myEdgeDirs[0] = aRes->myVertices[4].XYZ() - aRes->myVertices[0].XYZ();
    // Vertical
    aRes->myEdgeDirs[1] = aRes->myVertices[2].XYZ() - aRes->myVertices[0].XYZ();
    // LeftLower
    aRes->myEdgeDirs[2] = aRes->myVertices[2].XYZ() - aRes->myVertices[3].XYZ();
    // RightLower
    aRes->myEdgeDirs[3] = aRes->myVertices[6].XYZ() - aRes->myVertices[7].XYZ();
    // LeftUpper
    aRes->myEdgeDirs[4] = aRes->myVertices[0].XYZ() - aRes->myVertices[1].XYZ();
    // RightUpper
    aRes->myEdgeDirs[5] = aRes->myVertices[4].XYZ() - aRes->myVertices[5].XYZ();
  }
  // compute frustum normals
  computeNormals (aRes->myEdgeDirs, aRes->myPlanes);
  cacheVertexProjections (aRes);
  return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
}
修改办法:
  if (!isToScale && !isToTrsf)
  {
   aRes->myPixelTolerance=myPixelTolerance;
   aRes->myIsOrthographic=myIsOrthographic;
   aRes->myBuilder= myBuilder;
   aRes->myIsOrthographic = myIsOrthographic;
   aRes->myNearPickedPnt = myNearPickedPnt;
   aRes->myFarPickedPnt = myFarPickedPnt;
   aRes->myViewRayDir = myViewRayDir;
   aRes->myMousePos = myMousePos;
  
   for (int i = 0; i <6;++i)
   {
    aRes->myPlanes[i] = myPlanes[i];
   }
   for (int i = 0; i < 6; ++i)
   {
    aRes->myVertices[i] = myVertices[i];
   }
   for (int i = 0; i < 6; ++i)
   {
    aRes->myMaxVertsProjections[i] = myMaxVertsProjections[i];
   }
   for (int i = 0; i < 6; ++i)
   {
    aRes->myMinVertsProjections[i] = myMinVertsProjections[i];
   }
   for (int i = 0; i <3; ++i)
   {
    aRes->myMaxOrthoVertsProjections[i] = myMaxOrthoVertsProjections[i];
   }
   for (int i = 0; i <3; ++i)
   {
    aRes->myMinOrthoVertsProjections[i] = myMinOrthoVertsProjections[i];
   }
   for (int i = 0; i < 6; ++i)
   {
    aRes->myEdgeDirs[i] = myEdgeDirs[i];
   }
   return NCollection_Handle<SelectMgr_BaseFrustum>(aRes);
  }
posted @ 2015-11-12 15:20 隔壁老刘 阅读(567) | 评论 (0) | 编辑 收藏
 

2015年11月7日

C++智能指针类用不好害死人
C++智能指针类使用起来方便,但是不维护好引用计数,不能随时控制对象的释放,反而造成内存耗尽,这样说来,反而不能随时控制对象的生命周期,所以使用要谨慎啊。
posted @ 2015-11-07 21:43 隔壁老刘 阅读(592) | 评论 (0) | 编辑 收藏
 
仅列出标题