programing

행 대 장조 대 열 대 장조 혼동

telebox 2023. 10. 4. 21:15
반응형

행 대 장조 대 열 대 장조 혼동

저는 이 글을 많이 읽었는데, 읽을수록 혼란스러워집니다.

이해합니다. 되고, 됩니다.행 메이저 행은 메모리에 연속적으로 저장되고, 열 메이저 열은 메모리에 연속적으로 저장됩니다.그래서 만약 우리가 일련의 숫자를 가지고 있다면[1, ..., 9]과 같은 를 얻을 수 있습니다.다.

|1, 2, 3|
|4, 5, 6|
|7, 8, 9|

칼럼 장조(틀리면 수정)는 다음과 같습니다.

|1, 4, 7|
|2, 5, 8|
|3, 6, 9|

이것은 사실상 이전 행렬의 전치입니다.

나의 혼란: 는 아무런 가 없다고 뭐, 저는 별 차이가 없다고 봅니다.에서 (첫과 두 한 값을렬행,열)다로 1, 2, 3, ..., 9

행렬 곱셈이 동일하더라도 첫 번째 연속 요소를 취하고 두 번째 행렬 열과 곱합니다.그러니까 우리가 매트릭스를 가지고 있다고 치자.M:

|1, 0, 4| 
|5, 2, 7| 
|6, 0, 0|

가 앞의 행 을 곱한다면 R와 함께M,R x M우리는 다음을 얻을 것입니다.

|1*1 + 2*0 + 3*4, 1*5 + 2*2 + 3*7, etc|
|etc.. |
|etc.. |

가 열 장 을 곱한다면 C와 함께M,C x MC에, 다,에로부터 R x M

저는 정말 혼란스럽습니다, 만약 모든 것이 같다면, 왜 이 두 용어가 존재하는 것일까요?입니다.R해 볼 도 있어요 ...

내가 뭘 빼놓았나요?행 전공과 대학 전공이 내 행렬 수학에서 실제로 의미하는 바는 무엇입니까?저는 선형 대수 수업에서 항상 첫 번째 행렬의 행과 두 번째 행렬의 열을 곱한다는 것을 배웠습니다. 첫 번째 행렬이 열 장조인 경우 변경됩니까?우리는 이제 예제에서 했던 것처럼 두 번째 행렬의 열에 그것의 열을 곱해야 합니까 아니면 그것이 완전히 잘못된 것입니까?

어떤 해명이라도 해주시면 정말 감사하겠습니다!

편집: 제가 혼란을 겪고 있는 또 다른 주요 원인 중 하나는 GLM입니다. 그래서 행렬 유형 위를 맴돌면서 F12를 눌러 어떻게 구현되는지 확인했습니다. 벡터 배열이 보입니다. 3x3 행렬이 있으면 3개의 벡터 배열이 있습니다.제가 'col_type'을 본 벡터들의 종류를 보면, 그 벡터들 각각이 열을 나타낸다고 가정했고, 그래서 우리는 열-메이저 시스템을 가지고 있죠?

솔직히 잘 모르겠습니다.번역 행렬과 glm을 비교하기 위해 이 인쇄 함수를 썼습니다. 마지막 행에 glm으로 번역 벡터가 표시되고 마지막 열에 제 것이 표시됩니다.

enter image description here

이것은 혼란만 가중시킬 뿐입니다.각각의 벡터가 다음과 같은 것을 명확하게 알 수 있습니다.glmTranslate행렬은 행렬의 행을 나타냅니다.그럼.. 매트릭스가 행 메이저란 뜻이죠?제 행렬은 어떻습니까? (플로트 배열[16]을 사용하고 있습니다) 변환 값이 마지막 열에 있습니다. 행렬이 열 장조인데 지금은 그렇지 못했다는 뜻입니까? 머리 회전을 막으려고 합니다.

구현 세부사항과 용도를 혼동하고 계신 것 같습니다.

2차원 배열 또는 행렬부터 시작하겠습니다.

    | 1  2  3 |
    | 4  5  6 |
    | 7  8  9 |

문제는 컴퓨터 메모리가 바이트의 1차원 배열이라는 것입니다.논의를 쉽게 하기 위해 단일 바이트를 4개 그룹으로 그룹화하여 다음과 같이 설명합니다(각 단일, +-+는 바이트, 4바이트는 정수 값(32비트 운영 체제 가정).

   -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
    |       |       |       |       |       |       |       |       |  
   -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
       \/                   \       /
      one byte               one integer

    low memory    ------>                          high memory

또 다른 표현 방법은

따라서 문제는 2차원 구조(우리의 행렬)를 이 1차원 구조(즉, 메모리)에 매핑하는 방법입니다.이렇게 하는 방법에는 두 가지가 있습니다.

  1. 행 주 순서:이 순서대로 첫번째 행을 기억에 먼저 넣고, 두번째 행을 기억에 넣습니다.이렇게 하면 다음 사항을 기억할 수 있습니다.

     -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9   |
     -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

이 방법으로 우리는 다음과 같은 산술을 수행함으로써 배열의 주어진 요소를 찾을 수 있습니다.배열의 $M_{ij}$ 요소에 액세스하려고 합니다.첫다라고 .ptr 있습니다. 입니다.nCol, 다음을 통해 모든 요소를 찾을 수 있습니다.

     $M_{ij} = i*nCol + j$ 

이것이 어떻게 작동하는지 보려면 M_{02}(즉, 첫 번째 행, 세 번째 열 -- C는 0 기반임을 기억하십시오.

      $M_{02} = 0*3 + 2 = 2

배열의 세번째 요소에 접근합니다.

  1. 주열 순서:이 순서대로 첫 번째 열을 메모리에 먼저 넣고, 두 번째 열을 추가합니다.이렇게 하면 다음 사항을 기억할 수 있습니다.

     -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |   1   |   4   |   7   |   2   |   5   |   8   |   3   |   6   |   9   |
     -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

따라서 짧은 답변 - 행 장조 및 열 장조 형식은 두 개(또는 그 이상) 차원 배열이 메모리의 1차원 배열로 매핑되는 방법을 설명합니다.

대수학을 먼저 살펴봅시다. 대수학은 "메모리 레이아웃" 같은 개념조차 가지고 있지 않습니다.

대수적 pov로부터, MxN 실수 행렬은 오른쪽에 있는 |R^N 벡터에 작용하고 |R^M 벡터를 산출할 수 있습니다.

따라서, 시험에 앉아 MxN Matrix와 |R^N 벡터를 받았다면,사소한 연산들로 당신은 그것들을 곱하고 결과를 얻을 수 있습니다 - 그 결과가 옳은지 틀리는지는 교수님이 당신의 결과를 확인하기 위해 사용하는 소프트웨어가 내부적으로 열 장조를 사용하는지 행 장조 레이아웃을 사용하는지에 달려 있지 않습니다; 그것은 오직 당신이 행렬의 각 행의 수축을 계산할 때에만 달려있을 것입니다.벡터가 제대로 됩니다.

올바른 출력을 생성하기 위해 소프트웨어는 검사에서 한 것처럼 기본적으로 행렬의 각 행을 열 벡터로 수축시켜야 합니다.


따라서 열 메이저를 정렬하는 소프트웨어와 행 메이저 레이아웃을 사용하는 소프트웨어의 차이는 계산 방법아니라 방법입니다.

좀 더 구체적으로 말하면, 열 벡터와 함께 최상위 단일 행의 수축에 대한 레이아웃들의 차이는 단지 결정하기 위한 수단일 뿐입니다.

Where is the next element of the current row?
  • 행 메이저 레이아웃의 경우 메모리에서 바로 다음 버킷에 있는 요소입니다.
  • 열-메이저 레이아웃의 경우 버킷 M 버킷에 있는 요소입니다.

그것으로 끝입니다.


열/행 마법이 실제로 어떻게 호출되는지 보여주기 위해:

질문에 'c++' 태그를 붙이지 않았지만, '글렘'이라고 하셨기 때문에 C++와 잘 지낼 수 있을 것 같습니다.

C++의 표준 라이브러리에는 다른 까다로운 기능 외에도 []의 오버로드가 있는 악명 높은 짐승이 있습니다. 그 중 하나는 a(본질적으로 매우 지루한 것으로 정수형 숫자 3개만으로 구성됨)를 취할 수 있습니다.

그러나 이 작은 조각은 행 주 저장소 열 단위 또는 열 주 저장소 열 단위로 액세스하는 데 필요한 모든 것을 가지고 있습니다. 시작, 길이 및 보폭이 있습니다. 후자는 앞서 언급한 "다음 버킷까지의 거리"를 나타냅니다.

무엇을 사용하든 상관없습니다. 일관성을 유지하세요!

행 장조나 열 장조는 그저 관례일 뿐입니다.상관없어.C는 행 장조를 사용하고 포트란은 열을 사용합니다.둘 다 됩니다.프로그래밍 언어/환경에서 표준을 사용합니다.

둘이 일치하지 않으면 !@#$가 충족됩니다.

컬럼 메이저에 저장된 매트릭스에 행 메이저 어드레싱을 사용하면 잘못된 요소를 얻을 수 있고 배열의 끝을 읽을 수 있습니다.

Row major: A(i,j) element is at A[j + i * n_columns];  <---- mixing these up will
Col major: A(i,j) element is at A[i + j * n_rows];     <---- make your code fubar

행 장조와 열 장조에 대해 행렬 곱셈을 수행할 코드가 동일하다고 말하는 것은 올바르지 않습니다.

(물론 행렬 곱셈의 수학은 같습니다.)메모리에 두 개의 어레이가 있다고 가정해 보겠습니다.

X = [x1, x2, x3, x4]    Y = [y1, y2, y3, y4]

행렬이 열 장조에 저장되어 있다면 X, Y, X*Y는 다음과 같습니다.

IF COL MAJOR: [x1, x3  *  [y1, y3    =   [x1y1+x3y2, x1y3+x3y4
               x2, x4]     y2, y4]        x2y1+x4y2, x2y3+x4y4]

행렬을 행 장조에 저장할 경우 X, Y, X*Y는 다음과 같습니다.

IF ROW MAJOR:  [x1, x2    [y1, y2     = [x1y1+x2y3, x1y2+x2y4;
                x3, x4]    y3, y4]       x3y1+x4y3, x3y2+x4y4];

X*Y in memory if COL major   [x1y1+x3y2, x2y1+x4y2, x1y3+x3y4, x2y3+x4y4]
              if ROW major   [x1y1+x2y3, x1y2+x2y4, x3y1+x4y3, x3y2+x4y4]

여기는 아무 일도 없습니다.그건 단지 두가지 다른 관습일 뿐입니다.몇 마일이나 몇 킬로미터로 측정하는 것과 같습니다.어느 쪽이든 효과가 있습니다. 전환하지 않고 둘 사이를 왔다 갔다 할 수는 없습니다!

맞아요.시스템이 데이터를 행 주 구조로 저장했든 열 주 구조로 저장했든 상관 없습니다.그것은 의례적인 것입니다."이봐, 인간아.당신의 배열을 이쪽으로 저장하겠습니다.그럴 리가 없지, 어?"그러나 성과에 있어서는 중요합니다. 다음의 세 가지를 생각해 보세요.

1. 대부분의 어레이는 행 메이저 순서로 액세스됩니다.

2. 메모리에 액세스하면 메모리에서 직접 읽지 않습니다.먼저 일부 데이터 블록을 메모리에서 캐시로 저장한 다음 캐시에서 프로세서로 데이터를 읽습니다.

3. 원하는 데이터가 캐시에 없으면 캐시는 메모리에서 데이터를 다시 가져와야 합니다.

캐시가 메모리에서 데이터를 가져올 때는 로컬리티가 중요합니다.즉, 메모리에 데이터를 드문드문 저장하면 캐시가 메모리에서 데이터를 더 자주 가져와야 합니다.이 작업은 메모리에 액세스할 때 캐시에 액세스할 때보다 훨씬 느리기 때문에 프로그램 성능을 손상시킵니다.메모리 접근이 적을수록 프로그램 속도가 빨라집니다.따라서 데이터에 액세스하는 것이 로컬일 가능성이 높기 때문에 이 행 메이저 어레이가 더 효율적입니다.

'혼란'이라는 단어가 제목에 있는 걸 보면... 혼란의 정도를 이해할 수 있어요

첫째, 이것은 정말 문제입니다.

절대로, 절대로 "그것은 사용되지만..."이라는 생각에 굴복하지 마십시오.요즘 PC는..."

여기서 주요 문제는 다음과 같습니다. -Cache eviction strategy (LRU, FIFO, etc.) as @Y.C.Jung was beginning to touch on -Branch prediction -Pipelining (it's depth, etc) -Actual physical memory layout -Size of memory -Architecture of machine, (ARM, MIPS, Intel, AMD, Motorola, etc.)

이 답변은 현재 PC에 가장 적용 가능한 하버드 아키텍처인 폰 노이만 머신에 초점을 맞출 것입니다.

메모리 계층:

https://en.wikipedia.org/wiki/File:ComputerMemoryHierarchy.svgis

비용속도의 병치입니다.

오늘날의 표준 PC 시스템에서는 다음과 같습니다. SIZE: 500GB HDD > 8GB RAM > L2 Cache > L1 Cache > Registers. SPEED: 500GB HDD < 8GB RAM < L2 Cache < L1 Cache < Registers.

이것은 시간적 및 공간적 지역성의 개념으로 이어집니다.하나는 데이터가 어떻게 구성되는지(코드, 작업 세트 등)를 의미하며, 다른 하나는 물리적으로 데이터가 "메모리"에서 구성되는 을 의미합니다.

오늘날의 PC 대부분이 최근에는 리틀 엔디언(Intel) 기계라는 점을 감안하면 특정 리틀 엔디언 순서로 데이터를 메모리에 저장합니다.그것은 근본적으로 빅 엔디언과 다릅니다.

https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html (오히려 covers...swiftly;) )

(이 예를 간단히 설명하기 위해, 저는 일이 단일 항목에서 발생한다는 것을 '말하겠다'고 말씀드리겠습니다. 이는 잘못된 것이며, 전체 캐시 블록은 일반적으로 액세스되며 제조업체의 모델은 말할 것도 없습니다.)

그러니까, 이제 우리가 그걸 가지고 있으니까, 만일 당신의 프로그램이 요구했다면, 가정적으로1GB of data from your 500GB HDD, 에됩니다.8GB of RAM,cache조,registers에서 첫 때 두 을 수 있었습니다.next cache line,즉, 열 대신 다음 에 캐시 MISS가 표시됩니다.

캐시작기 때문에 가득 찼다고 가정하면, 퇴거 계획에 따라 '필요한 다음 데이터가 있는' 회선을 위한 공간을 마련하기 위해 회선이 퇴거됩니다.이 패턴이 반복되면 데이터 검색을 시도할 마다 미스가 발생합니다!

더 나쁜 것은 실제로 필요한 유효한 데이터가 있는 회선을 제거하는 것이므로 해당 회선을 몇 이고 검색해야 합니다.

이를 가리키는 용어는 다음과 같습니다.thrashing

https://en.wikipedia.org/wiki/Thrashing_(computer_science) 은 실제로 제대로 작성되지 않거나 오류가 발생하기 쉬운 시스템을 충돌시킬 수 있습니다.(Think window BSOD)...

반면에 데이터를 제대로 배치했다면(즉, 행 장조)...아직도 그리움이 남아있을 겁니다!

그러나 이러한 오류는 검색이 끝날 때마다 발생하는 것이지, 검색을 시도할 때마다 발생하는 것은 아닙니다.그 결과 시스템과 프로그램 성능에 큰 차이가 발생합니다.

매우 간단한 토막글:

#include<stdio.h>

#define NUM_ROWS 1024
#define NUM_COLS 1024

int COL_MAJOR [NUM_ROWS][NUM_COLS];

int main (void){
        int i=0, j=0;
        for(i; i<NUM_ROWS; i++){
                for(j; j<NUM_COLS; j++){
                        COL_MAJOR[j][i]=(i+j);//NOTE i,j order here!
                }//end inner for
        }//end outer for
return 0;
}//end main

이제 다음을 사용하여 컴파일합니다. gcc -g col_maj.c -o col.o

이제 다음 항목으로 실행합니다. time ./col.o real 0m0.009s user 0m0.003s sys 0m0.004s

이제 ROW 장조에 대해 다음을 반복합니다.

#include<stdio.h>

#define NUM_ROWS 1024
#define NUM_COLS 1024

int ROW_MAJOR [NUM_ROWS][NUM_COLS];

int main (void){
        int i=0, j=0;
        for(i; i<NUM_ROWS; i++){
                for(j; j<NUM_COLS; j++){
                        ROW_MAJOR[i][j]=(i+j);//NOTE i,j order here!
                }//end inner for
        }//end outer for
return 0;
}//end main

컴파일: terminal4$ gcc -g row_maj.c -o row.o 실행: time ./row.o real 0m0.005s user 0m0.001s sys 0m0.003s

보시다시피 로우 메이저가 상당히 빨랐습니다.

납득이 안 되나요?만약 여러분이 더 극단적인 예를 보고 싶다면: 행렬 1000000 x 1000000을 만들고 초기화한 후 전치하고 stdout으로 인쇄합니다. ''

(참고: *NIX 시스템에서는 ulimit을 무제한으로 설정해야 합니다.)

내 답변과 관련된 문제: -Optimizing compilers, they change a LOT of things! -Type of system -Please point any others out -This system has an Intel i5 processor

행 메이저와 열 메이저는 glUniformMatrix*()의 관점에서 볼 수 있습니다. 실제로 행렬은 변경되지 않았습니다. 항상 다음과 같습니다.

enter image description here

차이점은 매트릭스 클래스 실현입니다.매개변수로 저장된 16개의 Float가 glUniformMatrix*()를 통과하는 방법을 결정합니다.

행 주 행렬을 사용하는 경우 4x4 행렬의 메모리는 다음과 같습니다. (a11, a12, a13, a14, a21, a22, a23, a31, a32, a33, a34, a41, a42, a43, a44). 그 외 열 주 행렬의 경우 다음과 같습니다. (a11, a21, a31, a41, a12, a22, a32, a42, a13, a23, a33, a43, a41, a42, a43, a44).

glsl은 열 장 행렬이므로 16개의 부동 데이터(b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b15, b16)를 다음과 같이 읽습니다.

enter image description here

행 장조에서는 a11=b1, a12=b2, a13=b3, a14=b4, a21=b5, a22=b6,...이므로 glsl 행렬은 다음과 같이 변경됩니다.

열 장조에 있는 동안: a11=b1, a21=b2, a31=b3, a41=b4, a12=b5, a22=b6,...glsl 행렬은 다음과 같이 변경됩니다.

enter image description here

그것은 원래와 같습니다.그래서 줄 전공자는 전치가 필요하고 열 전공자는 그렇지 않습니다.

위 답변들의 짧은 부록.메모리에 거의 직접적으로 접근하는 C의 관점에서 행 장조 또는 열 장조 순서는 프로그램에 두 가지 방식으로 영향을 미칩니다. 1.메모리 2의 매트릭스 레이아웃에 영향을 미칩니다.순서 루프 형태로 유지해야 하는 요소 액세스 순서입니다.

  1. 앞의 답변들에서 상당히 자세히 설명되어 있으므로 2개를 추가하겠습니다.

오일러웍스의 답변은 그의 예에서 행 장 행렬을 사용하는 것이 계산의 현저한 저하를 가져왔다는 것을 지적합니다.글쎄, 그 말이 맞지만 결과는 동시에 뒤바뀔 수 있습니다.

루프 순서는 (행 위) {{행 위) {행렬 위에서 뭔가를 수행}}에 대한 순서였습니다.이는 이중 루프가 한 줄로 요소에 접근한 다음 다음 행으로 이동한다는 것을 의미합니다.예를 들어 A(0,1) -> A(0,2) -> A(0,3) -> ... -> A(0,N_ROWS) -> A(1,0) -> ...

이 경우 A가 행 메이저 형식으로 저장되어 있다면 메모리에서 요소가 선형으로 정렬될 수 있기 때문에 최소한의 캐시 미스가 발생할 것입니다.그렇지 않으면 열 메이저 형식의 메모리 액세스는 N_ROWs를 스트라이드로 사용하여 점프합니다.그래서 행장조가 더 빠릅니다.

이제, 우리는 실제로 (열 위로) {{행 위로) {행렬 위에서 무언가를 하라}}에 대해 루프를 전환할 수 있습니다.이 경우 결과는 정반대가 됩니다.루프가 선형 방식으로 열에 있는 요소를 읽기 때문에 열 장황도 계산이 더 빨라집니다.

그러므로, 여러분은 이것을 기억하는 편이 좋을 것입니다: 1.전통적인 C 프로그래밍 커뮤니티에서 행 메이저 형식을 선호하는 것처럼 보이지만 행 메이저 또는 열 메이저 저장 형식을 선택하는 것은 취향에 따라 결정됩니다. 2.당신이 좋아하는 것은 무엇이든 자유롭게 선택할 수 있지만 색인의 개념에 부합해야 합니다. 3.또한 이 점은 매우 중요합니다. 자신의 알고리즘을 적을 때는 원하는 저장 형식을 준수할 수 있도록 루프의 순서를 정해야 합니다. 4.한결같이.

위의 설명을 고려할 때, 여기 그 개념을 보여주는 코드 조각이 있습니다.

//----------------------------------------------------------------------------------------
// A generalized example of row-major, index/coordinate conversion for
// one-/two-dimensional arrays.
// ex: data[i] <-> data[r][c]
//
// Sandboxed at: http://swift.sandbox.bluemix.net/#/repl/5a077c462e4189674bea0810
//
// -eholley
//----------------------------------------------------------------------------------------

// Algorithm

let numberOfRows    = 3
let numberOfColumns = 5
let numberOfIndexes = numberOfRows * numberOfColumns

func index(row: Int, column: Int) -> Int {
    return (row * numberOfColumns) + column
}

func rowColumn(index: Int) -> (row: Int, column: Int) {
    return (index / numberOfColumns, index % numberOfColumns)
}

//----------------------------------------------------------------------------------------

// Testing

let oneDim = [
       0,    1,    2,    3,    4,
       5,    6,    7,    8,    9,
      10,   11,   12,   13,   14,
]

let twoDim = [
    [  0,    1,    2,    3,    4 ],
    [  5,    6,    7,    8,    9 ],
    [ 10,   11,   12,   13,   14 ],
]

for i1 in 0..<numberOfIndexes {
    let v1 = oneDim[i1]
    let rc = rowColumn(index: i1)
    let i2 = index(row: rc.row, column: rc.column)
    let v2 = oneDim[i2]
    let v3 = twoDim[rc.row][rc.column]
    print(i1, v1, i2, v2, v3, rc)
    assert(i1 == i2)
    assert(v1 == v2)
    assert(v2 == v3)
}

/* Output:
0 0 0 0 0 (row: 0, column: 0)
1 1 1 1 1 (row: 0, column: 1)
2 2 2 2 2 (row: 0, column: 2)
3 3 3 3 3 (row: 0, column: 3)
4 4 4 4 4 (row: 0, column: 4)
5 5 5 5 5 (row: 1, column: 0)
6 6 6 6 6 (row: 1, column: 1)
7 7 7 7 7 (row: 1, column: 2)
8 8 8 8 8 (row: 1, column: 3)
9 9 9 9 9 (row: 1, column: 4)
10 10 10 10 10 (row: 2, column: 0)
11 11 11 11 11 (row: 2, column: 1)
12 12 12 12 12 (row: 2, column: 2)
13 13 13 13 13 (row: 2, column: 3)
14 14 14 14 14 (row: 2, column: 4)
*/

오늘날 c/c++(eigen, armadillo, ...)에서 지원하는 라이브러리가 몇 개 있습니다.또한 [x,y,z]가 있는 사진은 슬라이스 단위로 파일에 저장되며, 이는 컬럼 메이저 순서입니다.2차원에서는 더 나은 순서를 선택하는 것이 혼란스러울 수 있지만, 더 높은 차원에서는 열 장차 순서가 많은 상황에서 유일한 해결책임이 분명합니다.

C의 저자들은 배열의 개념을 만들었지만 아마도 누군가가 배열을 행렬로 사용했을 것이라고 예상하지 못했을 것입니다.이미 모든 것이 포트란과 컬럼 메이저 순서로 구성되어 있는 상태에서 어레이가 어떻게 사용되는지를 본다면 저는 충격을 받을 것입니다.행-전공 순서는 단순히 열-전공 순서를 대체할 수 있지만 실제로 필요한 상황에서만 가능하다고 생각합니다(지금은 모릅니다).

여전히 누군가가 행주 순서로 도서관을 만든다는 것은 이상한 일입니다.그것은 불필요한 에너지와 시간의 낭비입니다.저는 언젠가 모든 것이 컬럼 메이저 오더가 되어 모든 혼란이 사라지기를 바랍니다.

언급URL : https://stackoverflow.com/questions/33862730/row-major-vs-column-major-confusion

반응형