고루틴은 go에서 제공하는 기능으로 go 키워드를 이용해 쉽게 병렬 처리를 가능하게 하는 기법이다.
나는 고루틴을 쓰면 쓰지 않은 것보다 항상 빠를 것이라고 생각했다. 그에 대한 결과가 아래 글에 나타나있다.
https://velog.io/@sunaookamisiroko/%EC%99%B8%EB%B0%95-%EC%8B%A0%EC%B2%AD-%EC%96%B4%ED%94%8C-API-go-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81
결론적으론 고루틴을 사용한 코드가 사용하지 않은 코드보다 더 느렸는데, 더 느린 이유가 궁금해서 검색하다가 다음 글을 찾았다.
https://appliedgo.net/concurrencyslower/
내가 했던 방식처럼 하나의 슬라이스를 여러 CPU 코어가 쓰게 되면 각 코어의 CPU 캐시가 슬라이스의 값을 복사해서 가지고 있게 되는데, 예를 들어 CPU 코어1에서 슬라이스의 인덱스 0번 값을 변경하면 CPU 코어2가 갖고 있던 캐시의 슬라이스 값은 불일치하게 된다.
이어서 CPU 코어1이 메인 메모리로 슬라이스의 값을 저장하게 되고 그것을 CPU 코어2가 다시 복사해서 캐시에 저장하게 되는데 이 과정이 반복되면서 오버헤드가 발생한다는 것이다.
나는 배열은 각각 독립적인 공간이라고 생각해서 각 고루틴이 하나의 인덱스만 맡아서 저장하면 빠르게 저장될 것이라고 생각했는데 그것이 아니라 CPU가 값을 저장할 때 자신의 공간으로 먼저 복사후 데이터를 수정하고 이후 메인 메모리에 저장한다는 사실을 간과했다.. 이렇게 또 하나 배워간다.