来自一个 "傻瓜 "的问题 - 页 126

 
Renat:

从什么时候开始,所有的数组都是静态的,所有的大小和指数也是静态的?

由于数组几乎都是动态的,而索引是变量,所以在调用的时候不能进行认真的静态检查。唯一要做的检查是元/rtti检查,这就是为什么对整个对象/描述的访问如此重要,而不是对一块内存的偶然性工作。

所以,让我们按顺序进行。 对于静态数组,在编译时一切都很容易检查,对吗?

对于动态的(有隐藏对象!),在运行时有元信息,对吗?当然有!当然有。

剩下的就是在被编译的函数的可执行代码中指定运行时检查。就这样吧!

我并不是说这是一件小事。好吧,斯拉瓦(斯特林戈)也知道他的东西。 现在到底谁容易呢?:)

// 毕竟:都是以四为单位完成的。

// 如果他们已经有了动态数组,那么就利用他们随处携带的元信息吧!

// 有了它,你就可以做更美妙的事情(比如让用户传递未知维度的数组)。

// 而在mql5(!)中,你甚至不能将一个二维数组的两个未知数传入一个函数。

// 即使是在古董蛤蟆中,你也能做到。:))

 
Renat:

别担心,一切都在很久以前就已经想好了。

破坏保护原则的后果我们非常清楚--这是 "在四月份我们又修复了12个关键的错误,允许突破虚拟机并获得对系统的控制 "的方式。

我并不关心,这个特殊解决方案的后果,甚至闻起来都不像 "控制系统"。我没有向你要任何这样的函数指针。 它最多只能使 "别人 "的内存崩溃 ,如果它 超出了数组的 控制 范围就不对了。
 
MetaDriver:

1.这是我的建议,即引入命名,从而引入严格的类型化,特别是因为它是唯一没有被命名覆盖的地方,因此很符合语言实体普遍化的思想。

2.都一样:首先,它是歪的,其次,它根本不具有普遍性。建议一种方法(1)将二维的mql-array复制到OpenCL缓冲区,而不需要不必要的重写和包装成结构,或者(2)使用(为了快速使用)你自己的函数ArrayCopy(...)来处理非二维数组。

// 对上一篇文章的突然性感到抱歉。真的没有必要。我听到 "不要把事情复杂化 "就很兴奋。因为这只会导致复杂化。

2a.我认为你对ArrayCopy()等函数的 "一维约束 "可以通过注释中的一个基本条款不痛不痒地弱化。"该函数对多维 数组也有效,前提是多维数组被完整地复制。"

这将消除很多问题。// 但不是所有的人,当然。

有两种方法,一种是单独复制一维数组,但这不好,因为OCL的界面会被数组弄得很乱。

第二种方法是将一维数组表示为二维数组,因为无论如何它都会通过磁带传递给OCL。所以它是这样的。顺便说一下,当维度改变时,非常的数据移动可以在OCL中通过复制数组的一部分来完成;这一切都取决于尺寸和它是否符合成本效益。

class CArrayTwo_merniy
  {
   float             a[];
   int               size_i;
   int               size_j;
public:
                     CArrayTwo_merniy(void){size_i=0;size_j=0;};
                    ~CArrayTwo_merniy(void){};
   void              Resize(int i,int j)
     {
      int size;
      if(j<size_j)// если уменьшаем j размер массива
        {
         for(int l=1;l<i;l++)
            for(int k=0;k<j;k++)
               a[l*i+k]=a[l*size_i+k];
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {size_i=i; size_j=j;}
         return;
        }
      else // иначе, если увеличиваем j размер массива
        {
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {
            for(int l=i-1;l>=0;l--)
               for(int k=j-1;k>=0;k--)
                  a[l*i+k]=a[l*size_i+k];
            size_i=i; size_j=j;
           }
        }
     };
   void set(int i,int j,float v)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)a[i*size_i+j]=v;
      else Print("Ошибка set ["+i+":"+j+"]");
     };
   float get(int i,int j)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)return(a[i*size_i+j]);
      else {Print("Ошибка get ["+i+":"+j+"]"); return(EMPTY_VALUE);}
     };
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CArrayTwo_merniy ar; string t;
   ar.Resize(3,3); int cnt=0;
   for(int i=0;i<3;i++)for(int j=0;j<3;j++){ar.set(i,j,(float)cnt); cnt++;}
   t="исх ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(5,5);
   t="5х5 "; for(int i=0;i<5;i++){for(int j=0;j<5;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(3,3);
   t="3х3 ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
  }
 
Urain:

有两种方法,一种是单独复制一维数组,但这不好,因为OCL的界面会被数组弄得很乱。

第二种方法是将一维数组表示为二维数组,因为无论如何它都会被磁带传递给OCL。所以它是这样的。顺便说一下,当维度改变时,非常的数据移动可以在OCL中通过复制数组的一部分来完成;这一切都取决于大小和它的成本效益如何。

многа многа букаф

我已经受够了这一切。:) 奥卡姆是歇斯底里的......。

;)

这里我有一个二维数组。我有它的sizeof(My2DArray)。我还需要什么来把它复制到缓冲区?无论如何,甚至没有人向我提供我的数组中的偏移量,使其成为一个变量。所以,没有。首先,我必须重写它(这导致了滞后),或者写我自己的二维数组。(!)嗯,这很好。那它是用来干什么的?这样我就可以安全了。(!) 就是这样,我笑了。:)))

 
MetaDriver:

这就是我受够了的一切。:) 奥卡姆是歇斯底里的......。

;)

:))

坦率地说,调整大小的开销是巨大的,但你可以通过使用OCL来削减这些东西。

但直接复制一个二维数组到OCL缓冲区。

我也不建议你在每次打喷嚏的时候都重新划分阵列。

因为它是相当适用的。

 
MetaDriver:

这就是我受够了的一切。奥卡姆是歇斯底里的...

;)

来吧,三组获取和调整大小的功能。

在你闷闷不乐的时候,我跪在地上为你写了它。

 
Urain:
得了吧,这话说得太多了,三个函数设置获取和调整大小
这很酷,我打赌。当他们让我们重载运算符时(别忘了让运算符"[ ]"和"="可重载,那么我们就会有乐趣。我们将能够在市场上销售我们的动态阵列。而且他们会接受的!而谁也不会接受他们--让我们关闭函数中多维 数组的气体 传输。:)
 
MetaDriver:
酷,这一点毫无疑问。当他们让我们的操作符重载时(别忘了让操作符"[ ]"可预加载,那么你就会很高兴。我们将在市场上销售我们自己的动态阵列。而且他们会接受的!谁也不会接受--让我们关闭函数中多维 数组的气体 传输。:)
我们不会忘记;)
 
mql5:
我们不会忘记;)
:))
 
MetaDriver:

我有一个二维数组。我有它的sizeof(My2DArray)。我还需要什么来把它复制到缓冲区?无论如何,甚至没有人向我提供我的数组中的偏移量,使其成为一个变量。所以,没有。首先,我必须重写它(这导致了滞后),或者自己写一个二维数组。(!)哦,我的天哪。那它是用来干什么的?这样我就可以安全了。(!) 就是这样,我笑了。:)))

亲爱的先生,请注意上下文。

1)当你从一个受控的安全环境跳到一个完全不受控的原始缓冲区时,是你负责与该二进制环境兼容。

2)当你写代码时,你要对该代码的架构负责。当你使用不同的结构时,不要抱怨说 "很难把一匹马和一只母鹿放在同一辆车上"。

3) 我建议你阅读CLBufferRead和CLBufferWrite 的描述--由于通用的void*引用,你可以向OpenCL传递任何类型的引用。而且还有偏移和大小之分。

uint  CLBufferRead(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из буфера для чтения, по умолчанию весь буфер
   );
uint  CLBufferWrite(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из массива для записи, по умолчанию весь массив
   );

我看得出,这个主题是凭空抓出来的。