Çaydanlıktan gelen sorular - sayfa 126

 
Renat :

Ve ne zamandan beri tüm diziler ve tüm indeksler ve boyutlar da statik hale geldi?

Diziler neredeyse her zaman dinamik olduğundan, dizinler değişken olduğundan, çağrı sırasında ciddi statik kontroller yapılamaz. Geriye yalnızca meta bilgi / rtti'ye dayalı kontroller yapmak kalıyor ve bu nedenle tüm nesneye / açıklamaya erişim sahibi olmak ve bir bellek parçasıyla rastgele çalışmamak çok önemlidir.

Teksas. Sırayla gidelim. Statik diziler için derleme sırasında her şey kolayca kontrol edilir, değil mi?

Dinamik olanlar için (ki bunlar gizli nesnelerdir!), çalışma zamanında meta-bilgi var, değil mi? Orada! Kesinlikle var.

Geriye yalnızca, derlenen işlevin yürütülebilir kodunda denetimin çalışma zamanını kaydetmek kalır. Ve bu kadar!

Ve bunun bir serseri olduğunu söylemiyorum. Eh, Slava (Stringo) da bir piç değil. Ve genel olarak, şimdi kim kolay? .. :)

// Sonunda: dördünde her şey bitti.

// Zaten dinamik diziler yaptıysanız, her yerde yanlarında taşıdıkları meta bilgileri kullanın!

// Buna sahip olarak, genellikle harika şeyler yapabilirsiniz (kullanıcının bilinmeyen boyutlarda dizileri transfer etmesine izin vermek gibi).

// mql5(!) içinde, her iki boyutu da bilinmeyen iki boyutlu bir diziyi bir fonksiyona bile geçiremezsiniz.

// Antika bir kurbağada bile yapabilirsin.. :))

 
Renat :

Endişelenme, her şey uzun zamandır düşünüldü.

Koruma ilkelerini ihlal etmenin sonuçlarının çok iyi farkındayız - "Nisan ayında 12 kritik hata daha düzeltilerek sanal makineden çıkmanıza ve sistem üzerinde kontrol sahibi olmanıza olanak tanıyan" yol budur.

endişelenmiyorum. Bu özel kararın sonuçları "sistem üzerinde kontrol" gibi kokmuyor bile. Sizden böyle bir işlev işaretçisi istemedim. Dizi aralığının dışına yanlış kontrol edilmesi durumunda zarar verebilecek maksimum "yabancı" hafızayı yok etmektir.
 
MetaDriver :

1. Bu yüzden bir adlandırma ve bu nedenle zor bir yazım eklemeyi önerdim. Ayrıca, bu, nominal tiplemenin kapsamadığı tek yerdir, bu nedenle dil varlıklarının evrenselleştirilmesi ideolojisine iyi uyum sağlar.

2. Ben de aynısını yapıyorum. Hepsi aynı: birincisi, çarpık, ikincisi, asla evrensel değil. Yapıları gereksiz yere yeniden yazmadan ve sarmadan iki boyutlu bir mql dizisini OpenCL arabelleğine kopyalamanın bir yolu ( 1 ). Veya ( 2 ) tek boyutlu olmayan diziler için (hız amacıyla) kendi ArrayCopy(..) işlevinizi kullanarak.

// Önceki gönderinin sertliği için özür dilerim. Gerçekten gereksiz. "Hadi karmaşıklaştırmayalım" konusunda heyecanlı. Çünkü bu sadece zorluklara yol açar.

2a. Çoğu durumda, ArrayCopy() gibi işlevler için "tek boyutlu kısıtlamanızın", yorumlardaki tek bir temel sorumluluk reddi ile ağrısız bir şekilde gevşetilebileceğini düşünüyorum: "İşlev ayrıca , tüm çok boyutlu dizinin kopyalanması koşuluyla çok boyutlu dizilerle de çalışır."

Birçok sorun ortadan kalkacaktı. // Ama elbette hepsi değil.

İki yol vardır, biri tek boyutlu dizileri ayrı ayrı kopyalamaktır, ancak bu iyi değil, çünkü OCL arayüzü dizilerle dolu olacak,

ve tek boyutlu bir diziyi iki boyutlu olarak göstermenin ikinci yolu, çünkü hala OCL'de bir bant ile iletilmektedir. Sonra böyle bir şey. Bu arada, boyutu değiştirirken veri hareketleri, dizinin bir kısmını kopyalayarak OCL'de yapılabilir, hepsi boyuta, ne kadar uygun maliyetli olduğuna bağlıdır.

 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 :

İki yol vardır, biri tek boyutlu dizileri ayrı ayrı kopyalamaktır, ancak bu iyi değil, çünkü OCL arayüzü dizilerle dolu olacak,

ve tek boyutlu bir diziyi iki boyutlu olarak göstermenin ikinci yolu, çünkü hala OCL'de bir bantla iletilmektedir. Sonra böyle bir şey. Bu arada, boyutu değiştirirken veri hareketleri, dizinin bir kısmını kopyalayarak OCL'de yapılabilir, hepsi boyuta, ne kadar uygun maliyetli olduğuna bağlıdır.

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

Doymak için yediğim tek şey bu. :) Ockham isterik..

;)

Burada iki boyutlu bir dizim var. Sizeof(My2DArray) var. Peki, arabelleğe kopyalamak için başka neye ihtiyacınız var ??? Her neyse, hiç kimse dizimde değişkenlerin yapması için bir ofset bile sağlamadı. Yani hayır. Önce onu yeniden yazmalısınız (ki bu da frenlere yol açar) veya kendi iki boyutlu dizinizi yazmalısınız. (!!) Peki, zashib. Ve neden bu? Ve güvende olmam için. (!) Her şey gülüyor. :)))

 
MetaDriver :

Doymak için yediğim tek şey bu. :) Ockham isterik..

;)

:))

Evet, dürüst olmak gerekirse, yeniden boyutlandırmanın ek yükü çok fazladır, ancak bu durumlar için OCL kullanmak azaltılabilir.

Ancak iki boyutlu bir dizinin doğrudan OCL arabelleğine kopyalanması.

Ve her hapşırmada diziyi yeniden bölümlendirmeyi tavsiye etmem.

Ve oldukça uygulanabilir.

 
MetaDriver :

Doymak için yediğim tek şey bu. :) Ockham isterik..

;)

Hadi, bir sürü bukafınız var, üç fonksiyon set get ve Resize

Hilosohstvuval buradayken sizin için özel olarak dizlerinize tehdit serpiştirin.

 
Urain :
Hadi, bir sürü bukafınız var, üç fonksiyon set get ve Resize
Pekala, kim tartışıyor. Operatörlerle aşırı yükleneceğimiz başka bir zaman (ve "[ ]" ve "=" operatörlerini aşırı yüklenebilir yapmayı unutmayacaklar, sonunda lafa geliyor. Dinamik dizilerimizi piyasada takas edeceğiz. Ve alacaklar. bir fonksiyondaki diziler . :)
 
MetaDriver :
Pekala, kim tartışıyor. İşte o zaman operatörlerle aşırı yükleneceğiz (ve "[ ]" operatörünü, sonra sizin lafanızı varsaymayı unutmayacaklar. Piyasadaki dinamik dizilerimizi takas edeceğiz. Ve alacaklar! :)
Unutmayalım ;)
 
mql5 :
Unutmayalım ;)
:))
 
MetaDriver :

Burada iki boyutlu bir dizim var. Sizeof(My2DArray) var. Peki, arabelleğe kopyalamak için başka neye ihtiyacınız var ??? Her neyse, hiç kimse dizimde değişkenlerin yapması için bir ofset bile sağlamadı. Yani hayır. Önce onu yeniden yazmalısınız (ki bu da frenlere yol açar) veya kendi iki boyutlu dizinizi yazmalısınız. (!!) Peki, zashib. Ve neden bu? Ve güvende olmam için. (!) Her şey gülüyor. :)))

Sevgili, bağlamı takip et.

1) Kontrollü ve güvenli bir ortamdan tamamen kontrolsüz bir ham arabelleğe atladığınızda, o ikili ortamla uyumluluktan siz sorumlusunuz.

2) Kod yazdığınızda, bu kodun mimarisinden siz sorumlusunuz. Ve farklı yapılar kullanırken "bir atı ve titreyen bir geyiği tek bir arabaya dizmek zordur" diye ağlamayın.

3) CLBufferRead ve CLBufferWrite açıklamalarını okumanızı tavsiye ederim - evrensel void* referansı nedeniyle, herhangi bir referans türünü OpenCL'ye aktarmak mümkündür. Ve yer değiştirmeler ve boyutlar var.

 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       // количество значений из массива для записи, по умолчанию весь массив
   );

Konunun basitçe parmaktan emildiğini görüyorum.

Neden: