comparison mc-codegen.c @ 296:284aa4eaab0d

case merge for cascade, table.
author kono
date Sun, 06 Jun 2004 02:40:32 +0900
parents 2437a94a1538
children 0f79c95df73a
comparison
equal deleted inserted replaced
295:2437a94a1538 296:284aa4eaab0d
1788 // cslist is already sorted 1788 // cslist is already sorted
1789 delta = 0; 1789 delta = 0;
1790 list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0)); 1790 list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0));
1791 count=1; 1791 count=1;
1792 for(p=0;cadr(cslist);cslist = cadr(cslist),count++) { 1792 for(p=0;cadr(cslist);cslist = cadr(cslist),count++) {
1793 // compute new delta
1793 delta1 = car(cadr(cslist))-car(cslist); 1794 delta1 = car(cadr(cslist))-car(cslist);
1795 // empty case
1794 if (!caddr(cslist)) count--; 1796 if (!caddr(cslist)) count--;
1795 if (delta==0) { 1797 if (delta==0) {
1798 // 2nd element
1796 caddr(list) = delta = delta1; 1799 caddr(list) = delta = delta1;
1797 if (p) cadr(p)=0; // terminate previous chunk 1800 if (p) cadr(p)=0; // terminate previous chunk
1798 } else if (delta1!=delta) { 1801 } else if (delta1!=delta) {
1799 // not contiguous, start new list 1802 // not contiguous, start new list
1800 caddr(cadddr(list)) = car(cslist); // max 1803 caddr(cadddr(list)) = car(cslist); // max
1801 car(cadddr(list)) = count; count=0; 1804 car(cadddr(list)) = count; count=0;
1802 delta = 0; 1805 delta = 0;
1803 list = list4(cadr(cslist),list,1,list3(0,0,0)); 1806 list = list4(cadr(cslist),list,1,list3(0,0,0));
1804 cadr(cadddr(list)) = car(cadr(cslist)); // min 1807 cadr(cadddr(list)) = car(cadr(cslist)); // min
1808 // prepare terminate point for next turn
1805 p=cslist; 1809 p=cslist;
1806 } 1810 }
1807 } 1811 }
1808 if (p) cadr(p)=0; // terminate previous chunk 1812 if (p) cadr(p)=0; // terminate previous chunk
1809 car(cadddr(list)) = count; 1813 car(cadddr(list)) = count;
1810 caddr(cadddr(list)) = car(cslist); // max 1814 caddr(cadddr(list)) = car(cslist); // max
1811 return list; 1815 return list;
1812 } 1816 }
1813 1817
1814 #define CASE_MERGE_RATE 80 1818 #define CASE_MERGE_RATE 70
1815 /*
1816 rate = (sum count(c_i))/(max-min)
1817 list3(count,min,max)
1818 */
1819 1819
1820 static int gcd(int i,int j) 1820 static int gcd(int i,int j)
1821 { 1821 {
1822 int k; 1822 int k;
1823 if (i<j) { k=i; i=j; j=k;} 1823 if (i<j) { k=i; i=j; j=k;}
1834 int 1834 int
1835 merge_chunk_p(int *delta,int max,int min,int *count,int delta1,int count1) 1835 merge_chunk_p(int *delta,int max,int min,int *count,int delta1,int count1)
1836 { 1836 {
1837 int range = max-min; 1837 int range = max-min;
1838 int g; 1838 int g;
1839 // compute possible merge delta
1839 g = gcd(*delta,delta1); 1840 g = gcd(*delta,delta1);
1840 g = gcd(g,range); 1841 g = gcd(g,range);
1841 range /= g; 1842 range /= g;
1842 *count = count1 = count1+*count; 1843 *count = count1 = count1+*count;
1843 *delta = g; 1844 *delta = g;
1844 #if 1 1845 #if 1
1845 printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n", 1846 if (count1*128>(range*128*CASE_MERGE_RATE/100)) {
1846 min,max,count1,g, 1847 printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n",
1847 ((double)count1)*100.0/range, 1848 min,max,count1,g,
1848 count1*128>(range*128*CASE_MERGE_RATE/100) 1849 ((double)count1)*100.0/range,
1849 ); 1850 count1*128>(range*128*CASE_MERGE_RATE/100)
1850 #endif 1851 );
1852 }
1853 #endif
1854 // count/((max-min)/delta) > 0.8
1851 return count1*128>(range*128*CASE_MERGE_RATE/100); 1855 return count1*128>(range*128*CASE_MERGE_RATE/100);
1852 } 1856 }
1853 1857
1854 /* 1858 /*
1855 merge possible chunk 1859 merge possible chunk
1856 input: list4(cslist,next,delta,list3(count,min,max)) 1860 input: list4(cslist,next,delta,list3(count,min,max))
1857 output: list3(continuous number of chunk,next,delta); 1861 output: list3(continuous number of chunk,next,delta,case_count);
1858 */ 1862 */
1859 1863
1860 static int 1864 static int
1861 merge_chunk(int cslist) 1865 merge_chunk(int cslist)
1862 { 1866 {
1863 int list = cslist; 1867 int list = cslist;
1864 int tail,last,max,min,i; 1868 int tail,last,max,min,i;
1865 int count,p,widest,delta=1; 1869 int count,c_count,p,widest,delta=1;
1866 int chunks = 0; 1870 int chunks = 0;
1867 while(cadr(list)) { 1871 while(cadr(list)) {
1868 p = cadddr(list); 1872 p = cadddr(list);
1869 count = car(p); max=caddr(p); 1873 c_count = count = car(p); max=caddr(p);
1870 widest = 1; last = list; 1874 widest = 1; last = list;
1871 delta = caddr(list); 1875 delta = caddr(list);
1876 // check possible merge against the end of the chunks
1872 for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) { 1877 for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) {
1873 p = cadddr(tail); 1878 p = cadddr(tail);
1874 min = cadr(p); 1879 min = cadr(p);
1875 if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) { 1880 if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) {
1876 widest = i+1; last = tail; 1881 // It is mergeable.
1882 widest = i+1; last = tail; c_count=count;
1877 } 1883 }
1878 } 1884 }
1879 chunks = list3(widest,chunks,delta); 1885 chunks = list4(widest,chunks,delta,c_count);
1886 // skip merged chunks
1880 list = cadr(last); 1887 list = cadr(last);
1881 } 1888 }
1882 if (list) chunks = list3(1,chunks,delta); 1889 // last one can remain.
1883 return reverse0(chunks); 1890 if (list) chunks = list4(1,chunks,caddr(list),car(cadddr(list)));
1884 } 1891 return chunks;
1885 1892 }
1886 static void 1893
1887 table_jump(int cslist) 1894 static int
1888 { 1895 table_jump(int count,int delta,int cslist)
1889 for(;cslist; cslist=cadr(cslist)) { 1896 {
1890 if (caddr(cslist)) 1897 int list;
1891 cmpdimm(car(cslist),csvalue1,caddr(cslist),0); 1898 for(;count-->0;cslist=cadr(cslist)) {
1892 } 1899 list = car(cslist);
1893 } 1900 printf("# table cases delta=%d count=%d min=%d max=%d\n",
1894 1901 caddr(cslist),car(cadddr(cslist)),
1895 static void 1902 cadr(cadddr(cslist)),caddr(cadddr(cslist))
1896 cascade_compare(int cslist) 1903 );
1897 { 1904 for(;list; list=cadr(list)) {
1898 for(;cslist; cslist=cadr(cslist)) { 1905 if (caddr(list))
1899 if (caddr(cslist)) 1906 cmpdimm(car(list),csvalue1,caddr(list),0);
1900 cmpdimm(car(cslist),csvalue1,caddr(cslist),0); 1907 }
1901 } 1908 }
1909 return cslist;
1910 }
1911
1912 static int
1913 cascade_compare(int count,int cslist)
1914 {
1915 int list;
1916 for(;count-->0;cslist=cadr(cslist)) {
1917 list = car(cslist);
1918 printf("# cascade cases delta=%d count=%d min=%d max=%d\n",
1919 caddr(cslist),car(cadddr(cslist)),
1920 cadr(cadddr(cslist)),caddr(cadddr(cslist))
1921 );
1922 for(;list; list=cadr(list)) {
1923 if (caddr(list))
1924 cmpdimm(car(list),csvalue1,caddr(list),0);
1925 }
1926 }
1927 return cslist;
1902 } 1928 }
1903 1929
1904 #define CASE_TABLE_COUNT 10 1930 #define CASE_TABLE_COUNT 10
1905 1931
1906 void 1932 void
1920 chunks++; 1946 chunks++;
1921 } 1947 }
1922 j = chunks; 1948 j = chunks;
1923 #endif 1949 #endif
1924 chunks = merge_chunk(cslist); 1950 chunks = merge_chunk(cslist);
1925 #if 1 1951 #if 0
1926 // chunks: list3(widest,next,delta); 1952 // chunks: list3(widest,next,delta);
1927 printf("# chunks %d = sum ",j); 1953 printf("# chunks %d = sum ",j);
1928 j = 0; 1954 j = 0;
1929 for(i=chunks;i;i=cadr(i)) { 1955 for(i=chunks;i;i=cadr(i)) {
1930 printf(" %d/%d",car(i),caddr(i)); 1956 printf(" %d/%d",car(i),caddr(i));
1931 j+=car(i); 1957 j+=car(i);
1932 } 1958 }
1933 printf(" sum = %d\n",j); 1959 printf(" sum = %d\n",j);
1934 #endif 1960 #endif
1935 fwddef(cslabel); 1961 fwddef(cslabel);
1936 for(;cslist;cslist=cadr(cslist)) { 1962 cslist = reverse0(cslist);
1937 printf("# case chunk delta=%d count=%d min=%d max=%d\n", 1963 for(;chunks;chunks=cadr(chunks)) {
1938 caddr(cslist),car(cadddr(cslist)), 1964 printf("# chunk count %d delta %d c_count %d\n",
1939 cadr(cadddr(cslist)),caddr(cadddr(cslist)) 1965 car(chunks),caddr(chunks),cadddr(chunks));
1940 ); 1966 if (cadddr(chunks)>CASE_TABLE_COUNT)
1941 if (cadddr(cslist)>CASE_TABLE_COUNT) 1967 cslist = table_jump(car(chunks),caddr(chunks),cslist);
1942 table_jump(car(cslist));
1943 else 1968 else
1944 cascade_compare(car(cslist)); 1969 cslist = cascade_compare(car(chunks),cslist);
1945 } 1970 }
1946 if (dlabel) jmp(dlabel); 1971 if (dlabel) jmp(dlabel);
1947 } 1972 }
1948 1973
1949 #endif 1974 #endif