코드 좀만 수정해서 분기예측 성공확률 높이면 내 방식이 훨씬 빠른건 너무 당연하고, 그렇게 안해도 배열거치는게 오버헤드 더큼
익명(220.71)2015-10-29 02:49
니 말대로라면 내 테스트가 말이 안되는거지 ㅋㄷㅋㄷ
codesafer(codesafer)2015-10-29 02:49
내 테스트 결과가 니말에 반한다고 바보야. ㅉㅉ
codesafer(codesafer)2015-10-29 02:50
아니지 니가 테스트 한건 int형이었으니까 배열 참조 오버헤드가 브랜치의 오버헤드를 넘어서지 않아서 그런거고. 원래 문제는 문자열 이었는데 이건 배열 참조시 항상 mov ecx, [[eax]], mov ecx,[상수] 급의 서로 다른 오버헤드를 가지게 되는데 [[]]의 오버헤드가 브랜치의 오버헤드를 뛰어 넘으니까 문제지
익명(220.71)2015-10-29 02:55
이해 감?
익명(220.71)2015-10-29 02:56
문자열 문자열 하는데, 리터럴 문자열의 주소 라는건 숫자라고 바보야 이해안감?
codesafer(codesafer)2015-10-29 02:57
둘 다 리터럴 문자열의 주소인 상수를 가져오는데, 내쪽은 배열의 시작주소를 베이스로 태그 참조를 추가적으로 수행하는거고 너는 즉치값인거야.
codesafer(codesafer)2015-10-29 02:58
배열 참조냐 즉치냐를 아래 테스트에서 반영한거고 이해 안감?
codesafer(codesafer)2015-10-29 02:58
mov 자체만 놓고 보면 당연히 배열을 거친 간접어드레싱이 더 느리지. 하지만 니쪽은 뒤에 cmp 와 jmp 가 기다리고 있다니깐 그러네 ㅋㄷ
codesafer(codesafer)2015-10-29 03:00
정확히 말하면 내쪽은 mov, 니쪽은 cmp mov jmp 혹은 cmp jmp mov 지
codesafer(codesafer)2015-10-29 03:01
내 mov 가 니 mov 보다 느린건 당연한거고.
codesafer(codesafer)2015-10-29 03:02
말이 되는 소리를 해라 문자열 배열의 한 원소의 주소는 런타임에 최소한 두단계를 거쳐야 얻을 수 있다.
익명(220.71)2015-10-29 03:02
이거 생각보다 오버헤드 커서 내꺼 오버헤드를 뛰어 넘는다니까
익명(220.71)2015-10-29 03:03
너랑 동일처리 되는 부분을 제하고 이야기 한거거든?
codesafer(codesafer)2015-10-29 03:04
니가 착각하는 모양인데, 문자열이고 자시고, printf 에 들어가기 전에 스택에 쌓아놓는건 그냥 주소야.
codesafer(codesafer)2015-10-29 03:05
다른 printf 의 파라메터에 주어진 수식들과 같이 연산할때, 내 경우는 branch hazard 가 없고, 너는 있지. 그 결과가 어떨까?
codesafer(codesafer)2015-10-29 03:06
지금 저 n 회 테스트는 어차피 양측 다 branch hazard 를 안고 간 경우여서 크게 차이가 안나는게 아래의 테스트 수준이거든?
codesafer(codesafer)2015-10-29 03:06
과거는 지금보다 훨씬 배열 참조가 빨랐지. 하지만, 니 말처럼 요즘 그 차이가 많이 줄었음. 그럼에도 2중 indirection 쪽도 최적화 되고 있기 때문에 아래의 유의미한 차이가 있는거다.
codesafer(codesafer)2015-10-29 03:09
[니가 착각하는 모양인데, 문자열이고 자시고, printf 에 들어가기 전에 스택에 쌓아놓는건 그냥 주소야.] 아니 지금 이런 기초적인거 따지자고 하는거 아닌데 누가 무슨 바본지 아나
익명(220.71)2015-10-29 03:10
니껀 런타임에 i가 for문에 의해서 계속 변하고 인덱스가 i&1에 의해 결정되고 나서 원하는 문자열의 주소는 문자열배열주소+워드사이즈*인덱스 를 통해 얻는 거고, 내 방식은 그냥 원하는 문자열의 주소가 상수로 딱 정해져 있음
익명(220.71)2015-10-29 03:11
계속 문자열 문자열 이야기 하니까 웃겨서 그렇지. 너는 아래 테스트가 잘못되었다고 주장하는데, 어차피 값 꺼내오는 메카니즘은 동일함. 아래에도 2중 indirection 이잖아? 안그래?
codesafer(codesafer)2015-10-29 03:11
얌마, 원래의 코드 자체가 현재 시간을 반영하는데 매번 같은 조건이 들어오니?
codesafer(codesafer)2015-10-29 03:12
쓸데없는걸로 트집이네. 비교 연산은 둘 다 똑같이 쓴거거든?
codesafer(codesafer)2015-10-29 03:12
물론 내꺼도 i가 for문에 의해서 계속 변하는건 마찬가지고 cmp를 통해 어떤 코드가 실행될지 브랜치 해야 된다는 점에서 오버헤드가 있는데 일단 분기하고 나면 문자열의 주소는 이미 상수로 구해져 있다고
익명(220.71)2015-10-29 03:12
나는 비트 연산을 썼지만 암튼.
codesafer(codesafer)2015-10-29 03:12
아래 코드는 안그러냐? ㅉㅉ
codesafer(codesafer)2015-10-29 03:13
내 말은 이 브랜치 오버헤드에서 오는 성능상 불이익 보다 문자열의 주소가 이미 상수로 구해져 있다는 점에서 오는 이득이 더 크다니까.
익명(220.71)2015-10-29 03:13
아래의 코드에서 상수로 박아드렸습니다만?
codesafer(codesafer)2015-10-29 03:14
배열값 매번 찾아 끄집어 오고 있고 3항 연산자는 상수로 박아드렸습니다만?
codesafer(codesafer)2015-10-29 03:15
문자열이라 하더라도 주소 끄집어오고 끝이니 마찬가지입니다만?
codesafer(codesafer)2015-10-29 03:16
일단 정리 해볼게, 1. 삼항연산자를 썼을때 브랜치 오버헤드가 있다.(배열을 사용 했을 땐 이 오버헤드가 없다) 2.배열을 사용 했을 때 원하는 문자열의 주소를 구하기 위한 오버헤드가 있다. (삼항 연산자를 사용햇을 땐 이 오버헤드가 없다.) 3.1의 오버헤드는 2의 오버헤드보다 작기 때문에 1이 더 빠르다.
익명(220.71)2015-10-29 03:16
내 경우엔 n 개의 문자열을 끄집어 오더라도 constant 한 시간이 반영됩니다만?
codesafer(codesafer)2015-10-29 03:16
3항 연산자일 경우는 3항 연산자를 도배해야 합니다만?
codesafer(codesafer)2015-10-29 03:16
난 3에 동의하지 않습니다만? ㅋㅋ 아래의 실험으로 말씀드렸습니다만?
codesafer(codesafer)2015-10-29 03:17
다시 설명하지만, printf 의 파라메터는 여러개고, 그 각각의 파라메터들도 최소 push 하나를 갖는 연산들이다.
codesafer(codesafer)2015-10-29 03:29
둘다 똑같이 비교연산을 수행한다고 했을 때, 1. 배열연산은, 비교, 배열참조 대입, 기타연산 1, 기타연산 2... 등등등 push 로 표현됨.
팝콘이다.
하나만 알고 둘은 모르는 코세. 자기가 알고있는 어줍잖은 지식이 세상의 전부인 양 착각하는 멍청이.
분명 원래 문제는 문자열에 관한 문제 였는데 왜 마음대로 int형으로 바꾸냐?
이해할려면 두군데를 봐야되고 더 느리고.. 답없다 ㅋㅋ 220.71.*.* <- 이게 쳐다보는게 느리다는 의미였다면 니 표현에도 문제가 있음.
그리고 이 테스트는 문자열 자체를 출력하는데 오버헤드가 엄청나서 3항연산자의 즉치값과 배열참조의 핵심 기능 비교가 안됨.
(버퍼로 출력이지만)
코세 // 코드 쳐다보고 이해 하는게 느리다는 표현 아니었음. 실제 작동 속도가 3항연산자로 할 경우 더 빠르다는 뜻 맞았음. 그렇다고 3항 연산자 자체가 더빠르다는 뜻은 아니었음. 무슨 말인지 이해감?
또한 니가 멍청한건 배열이든 즉치든 두 경우다 문자열은 리터럴 영역에 생성되어 있다는거다.
리터럴 영역의 주소를 배열에 담아서 가지고 있을 뿐이라는거지. 배열의 주소를 참조하느냐, 리터럴 상수를 참조하느냐 이기 때문에 내 테스트랑 의미상 차이가 없다.
와삭와삭쩝쩝
const char* test[] = {"AM", "PM"}; 에서 sizeof test 는 32비트 기준8, 64비트 기준 16이란 말이다. (리터럴 문자열의 시작 포인터 두 개를 담을 뿐)
기본도 없는 색히가 궁지렁거리네 췟.
니가 문자열 복사 코드로 이미 branch hazard 를 잔뜩 만들어 뒀으니 차이가 거의 날리 있나. ㅋㄷ
위의 두 클럭 차이는 유의미한 차이가 아니란 소리다.
삼항 연산자가 더 빠르다고 한적 없다. <-- 실제 작동 속도가 3항연산자로 할 경우 더 빠르다는 뜻 맞았음. <-- 이거 뭐하는 시츄에이션? ㅋㅋㅋㅋ
설사 2차원 배열을 이용해서 문자열을 복사한다 쳐도, 일반적으로 코드 볼륨이 커지면 메모리간 거리가 멀어지는 리터럴 영역보다, 스택에 클러스터링 되어 있는 쪽이 더 유리하다. 바부야.
(리터럴과 스택이 멀어지면 멀어질수록)
리터럴이 먼뜻인줄 모르나 보다. 코세야 너 설마 C나 C++로 코딩한거 컴파일해서 디스어셈블 해서 본적 없는건 아니겠지? 설마 그렇지는 않을것 같은데. ㅋㅋ 졌으면 졌다고 인정을 해라. 우기지좀 말고
다시 말하지만 나는 3항 연산자 자체가 더 빠르다고 한적이 없다. 아까 그 문제에서 3항 연산자를 써서 할 경우 문제 전체가 빨라진다는 거지. 이 말이 이해가 안가는 수준임?
보통은 배열에서 값 참조해서 복사하는것 보다 리터럴 값으로 주어진 값을 복사하는게 더 빠르기 때문이다 <--
배열을 한 번 거치는 비용이랑 3항연산자 비용이랑, 배열을 한 번 거치는 쪽이 빠름을 비교해서 보였다. 근데 뭐?
배열을 한 번 거치는 이유는 branch hazard 를 줄이기 위함인데, 니가 branch hazard 잔뜩 걸어놓고 유의미한 차이도 없는 수치를 올려 놓고 깩깩대고 있을뿐. 멍청아.
ㄴㄴ 너무 당연한 문장을 왜 발췌했어? int값을 예로 들면 배열 참조는 mov ecx,[eax]고 리터럴 값은 mov ecx,1 이야. 어떤게 빠르겠니? 물론 문자열은 다름.
그야 당연한거지. 그래서 아래에서 속도 비교 했잖아.
printf 들어가기 전에 3항연산자로 브랜치 한번 타는거랑, 배열 참조 연산 하는건데, 왜 브랜치는 쏙 빼고 이야기하냐? ㅋㄷ
결론은 내 실험에 의해서 배열 거치고 분기 없는것 보다 배열 안거치고 분기 있는게 더 빠르다는 거임.
할말 없지?
그래 결과가 유의미한 차이를 보이는건 아닌데 최소한 니가 말한것처럼 더 느리게 돌아가지는 않은건 인정하지?
printf 에 줄줄이 이어진 파라메터들이 늘어나면, 당연히 파라메터들을 먼저 연산해서 넣겠지, 그 때 연산이 많을수록 printf 에 들어가기 전에 branch hazard 에 의한 차이는 커지는게 당연한거고.
니 실험 수치는 유의미한 속도 차가 아니라니까 등신아. ㅋㅋ 테스트 처음해보나.
아니 그래서 내가 실험해서 결론은 내 방식이 더 빠르거나 최소한 느리지는 않다라는 결과가 나왔는데 인정 못하겠다는 거임?
몇 십 % 차이가 나야 유의미한거야 ㅉㅉ 내 테스트처럼.
파라메터와 수식이 늘어나면 달라진다니까 그러네 멍총아 조금이라도 내 방법이 더 빠를 수 밖에 없음.
노노 프로그램 복잡해 질수록 내 방식이 더 빠를 수 밖에 없음
컴파일러도 최대한 저런식으로 최적화해서 컴파일 하려고 얼마나 노력 하는데
mov 의 참조 연산과, cmp + jmp 와 어느쪽이 더 비싼지 산수가 안되는거냐? ㅋㅋ
글구 분기예측기 성능은 프로세서마다 엄청 차이나고, 니 코드는 일부러 분기예측 실패하도록 짰더만?
mov ecx,[eax] 이전에 eax를 구하기 위해서 필요한 연산은 생각 안하는 거냐?
단순하네 머리.. ㅋㅋ
역시 하나만 알고 둘은 모르는듯.
음꺽음꺽카아
뭔 개소리야? 단순히 같은 값을 추가하거나, 후에 결과값을 참조하지 않으면 for 문 자체를 축약해버리니까 막아놓은거지.
eax 가 니가 말하는 즉치값이지 등신아 상순데 그러면 cmp 들어가기 전에 상수 집어넣는것도 추가해야지 닭대가리니?
그래서 결론적으로 내가 테스트한 결과 내 방식이 더 빠르다는 유의미한 결과는 나오지 않았음 (인정함), 근데 바등 바등 한걸로 보아 더 느리지는 않은것은 거의 확실하다고 할 수 있음. 어떰?
for 문 자체를 축약할거면 뭐하러 for 를 돌림? 분기예측 당연히 막아야지 n 회 테스트가 의미가 있지.
바등바등한건 문자열 복사쪽이 무거우니까 그런거고. 내쪽 테스트에서 유의미한 결과가 나오는건 3항 연산자가 느리다는거야.
코드 좀만 수정해서 분기예측 성공확률 높이면 내 방식이 훨씬 빠른건 너무 당연하고, 그렇게 안해도 배열거치는게 오버헤드 더큼
니 말대로라면 내 테스트가 말이 안되는거지 ㅋㄷㅋㄷ
내 테스트 결과가 니말에 반한다고 바보야. ㅉㅉ
아니지 니가 테스트 한건 int형이었으니까 배열 참조 오버헤드가 브랜치의 오버헤드를 넘어서지 않아서 그런거고. 원래 문제는 문자열 이었는데 이건 배열 참조시 항상 mov ecx, [[eax]], mov ecx,[상수] 급의 서로 다른 오버헤드를 가지게 되는데 [[]]의 오버헤드가 브랜치의 오버헤드를 뛰어 넘으니까 문제지
이해 감?
문자열 문자열 하는데, 리터럴 문자열의 주소 라는건 숫자라고 바보야 이해안감?
둘 다 리터럴 문자열의 주소인 상수를 가져오는데, 내쪽은 배열의 시작주소를 베이스로 태그 참조를 추가적으로 수행하는거고 너는 즉치값인거야.
배열 참조냐 즉치냐를 아래 테스트에서 반영한거고 이해 안감?
mov 자체만 놓고 보면 당연히 배열을 거친 간접어드레싱이 더 느리지. 하지만 니쪽은 뒤에 cmp 와 jmp 가 기다리고 있다니깐 그러네 ㅋㄷ
정확히 말하면 내쪽은 mov, 니쪽은 cmp mov jmp 혹은 cmp jmp mov 지
내 mov 가 니 mov 보다 느린건 당연한거고.
말이 되는 소리를 해라 문자열 배열의 한 원소의 주소는 런타임에 최소한 두단계를 거쳐야 얻을 수 있다.
이거 생각보다 오버헤드 커서 내꺼 오버헤드를 뛰어 넘는다니까
너랑 동일처리 되는 부분을 제하고 이야기 한거거든?
니가 착각하는 모양인데, 문자열이고 자시고, printf 에 들어가기 전에 스택에 쌓아놓는건 그냥 주소야.
다른 printf 의 파라메터에 주어진 수식들과 같이 연산할때, 내 경우는 branch hazard 가 없고, 너는 있지. 그 결과가 어떨까?
지금 저 n 회 테스트는 어차피 양측 다 branch hazard 를 안고 간 경우여서 크게 차이가 안나는게 아래의 테스트 수준이거든?
과거는 지금보다 훨씬 배열 참조가 빨랐지. 하지만, 니 말처럼 요즘 그 차이가 많이 줄었음. 그럼에도 2중 indirection 쪽도 최적화 되고 있기 때문에 아래의 유의미한 차이가 있는거다.
[니가 착각하는 모양인데, 문자열이고 자시고, printf 에 들어가기 전에 스택에 쌓아놓는건 그냥 주소야.] 아니 지금 이런 기초적인거 따지자고 하는거 아닌데 누가 무슨 바본지 아나
니껀 런타임에 i가 for문에 의해서 계속 변하고 인덱스가 i&1에 의해 결정되고 나서 원하는 문자열의 주소는 문자열배열주소+워드사이즈*인덱스 를 통해 얻는 거고, 내 방식은 그냥 원하는 문자열의 주소가 상수로 딱 정해져 있음
계속 문자열 문자열 이야기 하니까 웃겨서 그렇지. 너는 아래 테스트가 잘못되었다고 주장하는데, 어차피 값 꺼내오는 메카니즘은 동일함. 아래에도 2중 indirection 이잖아? 안그래?
얌마, 원래의 코드 자체가 현재 시간을 반영하는데 매번 같은 조건이 들어오니?
쓸데없는걸로 트집이네. 비교 연산은 둘 다 똑같이 쓴거거든?
물론 내꺼도 i가 for문에 의해서 계속 변하는건 마찬가지고 cmp를 통해 어떤 코드가 실행될지 브랜치 해야 된다는 점에서 오버헤드가 있는데 일단 분기하고 나면 문자열의 주소는 이미 상수로 구해져 있다고
나는 비트 연산을 썼지만 암튼.
아래 코드는 안그러냐? ㅉㅉ
내 말은 이 브랜치 오버헤드에서 오는 성능상 불이익 보다 문자열의 주소가 이미 상수로 구해져 있다는 점에서 오는 이득이 더 크다니까.
아래의 코드에서 상수로 박아드렸습니다만?
배열값 매번 찾아 끄집어 오고 있고 3항 연산자는 상수로 박아드렸습니다만?
문자열이라 하더라도 주소 끄집어오고 끝이니 마찬가지입니다만?
일단 정리 해볼게, 1. 삼항연산자를 썼을때 브랜치 오버헤드가 있다.(배열을 사용 했을 땐 이 오버헤드가 없다) 2.배열을 사용 했을 때 원하는 문자열의 주소를 구하기 위한 오버헤드가 있다. (삼항 연산자를 사용햇을 땐 이 오버헤드가 없다.) 3.1의 오버헤드는 2의 오버헤드보다 작기 때문에 1이 더 빠르다.
내 경우엔 n 개의 문자열을 끄집어 오더라도 constant 한 시간이 반영됩니다만?
3항 연산자일 경우는 3항 연산자를 도배해야 합니다만?
난 3에 동의하지 않습니다만? ㅋㅋ 아래의 실험으로 말씀드렸습니다만?
다시 설명하지만, printf 의 파라메터는 여러개고, 그 각각의 파라메터들도 최소 push 하나를 갖는 연산들이다.
둘다 똑같이 비교연산을 수행한다고 했을 때, 1. 배열연산은, 비교, 배열참조 대입, 기타연산 1, 기타연산 2... 등등등 push 로 표현됨.
2. 3항연산은, 비교, 조건분기, 즉치 대입, 분기, 즉치 대입, 기타연산1, 기타연산 2... 등등등 push 로 표현됨.
다만 모든 코드를 도는건 아니니까, 비교->조건분기->즉치대입 루트를 타든지, 아니면 비교->조건분기->즉치대입->분기 루트를 타든지 둘 중 하나지.
하지만 니쪽은 기타연산에 들어가기 전에 파이프라인이 다 깨져 있고, 나는 파이프라인을 지키고 있지. (코드가 커질수록 파이프라인이 깨질 확률이 높다. 지금 테스트는 가장 니쪽에 유리한 테스트들이야. 내가한거건 니가한거건)
고로 보다 부드럽게 기타연산 1, 기타연산 2 등으로 들어가게 되는건 1번 배열 참조임.
애썼다만 하나만 알고 둘은 모르는건 너야. 니 말대로라면 내 아래코드의 결과가 바뀌었어야 해.
게다가 3항연산자는 오전 오후 저녁 같은 3개 이상의 표기를 해야할때 걍 GG 지. 변화하는 수치연산에선 당연히 배열을 쓸 수 없지만 말야.
졌다. 우기기 실패 젠장 ㅋ
예쁘네~ ㅋㅋ
코세가 실수할 날을 기다리며 언젠가 다시 돌아온다
얘들아 잘 배워둬라.
자주와서 놀아 : )